diff --git a/sys/dev/kbd/kbdtables.h b/sys/dev/kbd/kbdtables.h new file mode 100644 index 000000000000..013cf59e9b7f --- /dev/null +++ b/sys/dev/kbd/kbdtables.h @@ -0,0 +1,265 @@ +/* + * Copyright (C) 1992, 1993 Søren Schmidt + * + * This program is free software; you may redistribute it and/or + * modify it, provided that it retain the above copyright notice + * and the following disclaimer. + * + * 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. + * + * Søren Schmidt Email: sos@kmd-ac.dk + * Tritonvej 36 UUCP: ...uunet!dkuug!kmd-ac!sos + * DK9210 Aalborg SO Phone: +45 9814 8076 + */ + +#if defined(DKKEYMAP) + +keymap_t key_map = { 107, /* DK iso8859 keymap */ +/* alt + * scan cntrl alt alt cntrl + * code base shift cntrl shift alt shift cntrl shift spcl flgs + * --------------------------------------------------------------------------- + */ +/* sc=00 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=01 */ 0x1B, 0x1B, NOP, NOP, 0x1B, 0x1B, NOP, NOP, 0x33, 0x00, +/* sc=02 */ '1', '!', NOP, NOP, '1', '!', NOP, NOP, 0x33, 0x00, +/* sc=03 */ '2', '"', 0x00, 0x00, '@', '"', 0x00, 0x00, 0x00, 0x00, +/* sc=04 */ '3', '#', NOP, NOP, 0x9E, '#', NOP, NOP, 0x33, 0x00, +/* sc=05 */ '4', 0xA4, NOP, NOP, '$', 0xA4, NOP, NOP, 0x33, 0x00, +/* sc=06 */ '5', '%', NOP, NOP, '5', '%', NOP, NOP, 0x33, 0x00, +/* sc=07 */ '6', '&', NOP, NOP, '6', '&', NOP, NOP, 0x33, 0x00, +/* sc=08 */ '7', '/', NOP, NOP, '{', '/', NOP, NOP, 0x33, 0x00, +/* sc=09 */ '8', '(', 0x1B, 0x1B, '[', '(', 0x1B, 0x1B, 0x00, 0x00, +/* sc=0a */ '9', ')', 0x1D, 0x1D, ']', ')', 0x1D, 0x1D, 0x00, 0x00, +/* sc=0b */ '0', '=', NOP, NOP, '}', '=', NOP, NOP, 0x33, 0x00, +/* sc=0c */ '+', '?', NOP, NOP, '+', '?', NOP, NOP, 0x33, 0x00, +/* sc=0d */ '\'', '`', NOP, NOP, '|', '`', NOP, NOP, 0x33, 0x00, +/* sc=0e */ 0x08, 0x08, 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00, +/* sc=0f */ 0x09, 0x08, NOP, NOP, 0x09, 0x08, NOP, NOP, 0x33, 0x00, +/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01, +/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01, +/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01, +/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01, +/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01, +/* sc=15 */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01, +/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01, +/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01, +/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01, +/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01, +/* sc=1a */ 0xE5, 0xC5, NOP, NOP, 0x86, 0x8F, NOP, NOP, 0x33, 0x01, +/* sc=1b */ '"', '^', 0x1E, 0x1E, '~', '^', 0x1E, 0x1E, 0x00, 0x00, +/* sc=1c */ 0x0D, 0x0D, 0x0A, 0x0A, 0x0D, 0x0D, 0x0A, 0x0A, 0x00, 0x00, +/* sc=1d */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00, +/* sc=1e */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01, +/* sc=1f */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01, +/* sc=20 */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01, +/* sc=21 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01, +/* sc=22 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01, +/* sc=23 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01, +/* sc=24 */ 'j', 'J', 0x0A, 0x0A, 'j', 'J', 0x0A, 0x0A, 0x00, 0x01, +/* sc=25 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01, +/* sc=26 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01, +/* sc=27 */ 0xE6, 0xC6, NOP, NOP, 0x91, 0x92, NOP, NOP, 0x33, 0x01, +/* sc=28 */ 0xF8, 0xD8, NOP, NOP, 0x9B, 0x9D, NOP, NOP, 0x33, 0x01, +/* sc=29 */ 0xBD, 0xA7, NOP, NOP, 0xBD, 0xA7, NOP, NOP, 0x33, 0x00, +/* sc=2a */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00, +/* sc=2b */ '\'', '*', NOP, NOP, '\'', '*', NOP, NOP, 0x33, 0x00, +/* sc=2c */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01, +/* sc=2d */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01, +/* sc=2e */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01, +/* sc=2f */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01, +/* sc=30 */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01, +/* sc=31 */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01, +/* sc=32 */ 'm', 'M', 0x0D, 0x0D, 'm', 'M', 0x0D, 0x0D, 0x00, 0x01, +/* sc=33 */ ',', ';', NOP, NOP, ',', ';', NOP, NOP, 0x33, 0x00, +/* sc=34 */ '.', ':', NOP, NOP, '.', ':', NOP, NOP, 0x33, 0x00, +/* sc=35 */ '-', '_', 0x1F, 0x1F, '-', '_', 0x1F, 0x1F, 0x00, 0x00, +/* sc=36 */ RSH, RSH, RSH, RSH, RSH, RSH, RSH, RSH, 0xFF, 0x00, +/* sc=37 */ '*', '*', '*', '*', '*', '*', '*', '*', 0x33, 0x00, +/* sc=38 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00, +/* sc=39 */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 0x00, 0x00, +/* sc=3a */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00, +/* sc=3b */ F( 1), F(13), F(25), F(37), S( 1), S(11), S( 1), S(11), 0xFF, 0x00, +/* sc=3c */ F( 2), F(14), F(26), F(38), S( 2), S(12), S( 2), S(12), 0xFF, 0x00, +/* sc=3d */ F( 3), F(15), F(27), F(39), S( 3), S(13), S( 3), S(13), 0xFF, 0x00, +/* sc=3e */ F( 4), F(16), F(28), F(40), S( 4), S(14), S( 4), S(14), 0xFF, 0x00, +/* sc=3f */ F( 5), F(17), F(29), F(41), S( 5), S(15), S( 5), S(15), 0xFF, 0x00, +/* sc=40 */ F( 6), F(18), F(30), F(42), S( 6), S(16), S( 6), S(16), 0xFF, 0x00, +/* sc=41 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00, +/* sc=42 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00, +/* sc=43 */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00, +/* sc=44 */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00, +/* sc=45 */ NLK, NLK, NLK, NLK, NLK, NLK, NLK, NLK, 0xFF, 0x00, +/* sc=46 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00, +/* sc=47 */ F(49), '7', '7', '7', '7', '7', '7', '7', 0x80, 0x02, +/* sc=48 */ F(50), '8', '8', '8', '8', '8', '8', '8', 0x80, 0x02, +/* sc=49 */ F(51), '9', '9', '9', '9', '9', '9', '9', 0x80, 0x02, +/* sc=4a */ F(52), '/', '/', '/', '/', '/', '/', '/', 0x80, 0x02, +/* sc=4b */ F(53), '4', '4', '4', '4', '4', '4', '4', 0x80, 0x02, +/* sc=4c */ NOP, '5', '5', '5', '5', '5', '5', '5', 0x80, 0x02, +/* sc=4d */ F(55), '6', '6', '6', '6', '6', '6', '6', 0x80, 0x02, +/* sc=4e */ F(56), '+', '+', '+', '+', '+', '+', '+', 0x80, 0x02, +/* sc=4f */ F(57), '1', '1', '1', '1', '1', '1', '1', 0x80, 0x02, +/* sc=50 */ F(58), '2', '2', '2', '2', '2', '2', '2', 0x80, 0x02, +/* sc=51 */ F(59), '3', '3', '3', '3', '3', '3', '3', 0x80, 0x02, +/* sc=52 */ F(60), '0', '0', '0', '0', '0', '0', '0', 0x80, 0x02, +/* sc=53 */ 0x7F, '.', '.', '.', '.', '.', '.', '.', 0x00, 0x02, +/* sc=54 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=56 */ '<', '>', 0x1C, 0x1C, '\\', '>', 0x1C, 0x1C, 0x00, 0x00, +/* sc=57 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00, +/* sc=58 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00, +/* sc=59 */ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x02, +/* sc=5a */ RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, 0xFF, 0x00, +/* sc=5b */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x00, +/* sc=5c */ '*', '*', '*', '*', '*', '*', '*', '*', 0x00, 0x00, +/* sc=5d */ RALT, RALT, RALT, RALT, RALT, RALT, RALT, RALT, 0xFF, 0x00, +/* sc=5e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00, +/* sc=5f */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00, +/* sc=60 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00, +/* sc=61 */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00, +/* sc=62 */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00, +/* sc=63 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00, +/* sc=64 */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00, +/* sc=65 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00, +/* sc=66 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00, +/* sc=67 */ F(54), F(54), F(54), F(54), F(54), F(54), F(54), F(54), 0xFF, 0x00, +/* sc=68 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00, +}; + +#else + +keymap_t key_map = { 107, /* US iso8859 keymap */ +/* alt + * scan cntrl alt alt cntrl + * code base shift cntrl shift alt shift cntrl shift spcl flgs + * --------------------------------------------------------------------------- + */ +/* sc=00 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=01 */ 0x1B, 0x1B, NOP, NOP, 0x1B, 0x1B, NOP, NOP, 0x33, 0x00, +/* sc=02 */ '1', '!', NOP, NOP, '1', '!', NOP, NOP, 0x33, 0x00, +/* sc=03 */ '2', '@', 0x00, 0x00, '2', '@', 0x00, 0x00, 0x00, 0x00, +/* sc=04 */ '3', '#', NOP, NOP, '3', '#', NOP, NOP, 0x33, 0x00, +/* sc=05 */ '4', '$', NOP, NOP, '4', '$', NOP, NOP, 0x33, 0x00, +/* sc=06 */ '5', '%', NOP, NOP, '5', '%', NOP, NOP, 0x33, 0x00, +/* sc=07 */ '6', '^', 0x1E, 0x1E, '6', '^', 0x1E, 0x1E, 0x00, 0x00, +/* sc=08 */ '7', '&', NOP, NOP, '7', '&', NOP, NOP, 0x33, 0x00, +/* sc=09 */ '8', '*', NOP, NOP, '8', '*', NOP, NOP, 0x33, 0x00, +/* sc=0a */ '9', '(', NOP, NOP, '9', '(', NOP, NOP, 0x33, 0x00, +/* sc=0b */ '0', ')', NOP, NOP, '0', ')', NOP, NOP, 0x33, 0x00, +/* sc=0c */ '-', '_', 0x1F, 0x1F, '-', '_', 0x1F, 0x1F, 0x00, 0x00, +/* sc=0d */ '=', '+', NOP, NOP, '=', '+', NOP, NOP, 0x33, 0x00, +/* sc=0e */ 0x08, 0x08, 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00, +/* sc=0f */ 0x09, 0x08, NOP, NOP, 0x09, 0x08, NOP, NOP, 0x33, 0x00, +/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01, +/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01, +/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01, +/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01, +/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01, +/* sc=15 */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01, +/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01, +/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01, +/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01, +/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01, +/* sc=1a */ '[', '{', 0x1B, 0x1B, '[', '{', 0x1B, 0x1B, 0x00, 0x00, +/* sc=1b */ ']', '}', 0x1D, 0x1D, ']', '}', 0x1D, 0x1D, 0x00, 0x00, +/* sc=1c */ 0x0D, 0x0D, 0x0A, 0x0A, 0x0D, 0x0D, 0x0A, 0x0A, 0x00, 0x00, +/* sc=1d */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00, +/* sc=1e */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01, +/* sc=1f */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01, +/* sc=20 */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01, +/* sc=21 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01, +/* sc=22 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01, +/* sc=23 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01, +/* sc=24 */ 'j', 'J', 0x0A, 0x0A, 'j', 'J', 0x0A, 0x0A, 0x00, 0x01, +/* sc=25 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01, +/* sc=26 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01, +/* sc=27 */ ';', ':', NOP, NOP, ';', ':', NOP, NOP, 0x33, 0x00, +/* sc=28 */ '\'', '"', NOP, NOP, '\'', '"', NOP, NOP, 0x33, 0x00, +/* sc=29 */ '`', '~', NOP, NOP, '`', '~', NOP, NOP, 0x33, 0x00, +/* sc=2a */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00, +/* sc=2b */ '\\', '|', 0x1C, 0x1C, '\\', '|', 0x1C, 0x1C, 0x00, 0x00, +/* sc=2c */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01, +/* sc=2d */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01, +/* sc=2e */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01, +/* sc=2f */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01, +/* sc=30 */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01, +/* sc=31 */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01, +/* sc=32 */ 'm', 'M', 0x0D, 0x0D, 'm', 'M', 0x0D, 0x0D, 0x00, 0x01, +/* sc=33 */ ',', '<', NOP, NOP, ',', '<', NOP, NOP, 0x33, 0x00, +/* sc=34 */ '.', '>', NOP, NOP, '.', '>', NOP, NOP, 0x33, 0x00, +/* sc=35 */ '/', '?', NOP, NOP, '/', '?', NOP, NOP, 0x33, 0x00, +/* sc=36 */ RSH, RSH, RSH, RSH, RSH, RSH, RSH, RSH, 0xFF, 0x00, +/* sc=37 */ '*', '*', 0x0A, 0x0A, '*', '*', 0x0A, 0x0A, 0x33, 0x00, +/* sc=38 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00, +/* sc=39 */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 0x00, 0x00, +/* sc=3a */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00, +/* sc=3b */ F( 1), F(13), F(25), F(37), S( 1), S(11), S( 1), S(11), 0xFF, 0x00, +/* sc=3c */ F( 2), F(14), F(26), F(38), S( 2), S(12), S( 2), S(12), 0xFF, 0x00, +/* sc=3d */ F( 3), F(15), F(27), F(39), S( 3), S(13), S( 3), S(13), 0xFF, 0x00, +/* sc=3e */ F( 4), F(16), F(28), F(40), S( 4), S(14), S( 4), S(14), 0xFF, 0x00, +/* sc=3f */ F( 5), F(17), F(29), F(41), S( 5), S(15), S( 5), S(15), 0xFF, 0x00, +/* sc=40 */ F( 6), F(18), F(30), F(42), S( 6), S(16), S( 6), S(16), 0xFF, 0x00, +/* sc=41 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00, +/* sc=42 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00, +/* sc=43 */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00, +/* sc=44 */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00, +/* sc=45 */ NLK, NLK, NLK, NLK, NLK, NLK, NLK, NLK, 0xFF, 0x00, +/* sc=46 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00, +/* sc=47 */ F(49), '7', '7', '7', '7', '7', '7', '7', 0x80, 0x02, +/* sc=48 */ F(50), '8', '8', '8', '8', '8', '8', '8', 0x80, 0x02, +/* sc=49 */ F(51), '9', '9', '9', '9', '9', '9', '9', 0x80, 0x02, +/* sc=4a */ F(52), '-', '-', '-', '-', '-', '-', '-', 0x80, 0x02, +/* sc=4b */ F(53), '4', '4', '4', '4', '4', '4', '4', 0x80, 0x02, +/* sc=4c */ NOP, '5', '5', '5', '5', '5', '5', '5', 0x80, 0x02, +/* sc=4d */ F(55), '6', '6', '6', '6', '6', '6', '6', 0x80, 0x02, +/* sc=4e */ F(56), '+', '+', '+', '+', '+', '+', '+', 0x80, 0x02, +/* sc=4f */ F(57), '1', '1', '1', '1', '1', '1', '1', 0x80, 0x02, +/* sc=50 */ F(58), '2', '2', '2', '2', '2', '2', '2', 0x80, 0x02, +/* sc=51 */ F(59), '3', '3', '3', '3', '3', '3', '3', 0x80, 0x02, +/* sc=52 */ F(60), '0', '0', '0', '0', '0', '0', '0', 0x80, 0x02, +/* sc=53 */ 0x7F, '.', 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00, 0x02, +/* sc=54 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=56 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=57 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00, +/* sc=58 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00, +/* sc=59 */ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, +/* sc=5a */ RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, 0xFF, 0x00, +/* sc=5b */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x00, +/* sc=5c */ '*', '*', '*', '*', '*', '*', '*', '*', 0x00, 0x00, +/* sc=5d */ RALT, RALT, RALT, RALT, RALT, RALT, RALT, RALT, 0xFF, 0x00, +/* sc=5e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00, +/* sc=5f */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00, +/* sc=60 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00, +/* sc=61 */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00, +/* sc=62 */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00, +/* sc=63 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00, +/* sc=64 */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00, +/* sc=65 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00, +/* sc=66 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00, +/* sc=67 */ F(54), F(54), F(54), F(54), F(54), F(54), F(54), F(54), 0xFF, 0x00, +/* sc=68 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00, +}; + +#endif + +fkeytab_t fkey_tab[60] = { +/* 00-03 */ {"\033[M", 3}, {"\033[N", 3}, {"\033[O", 3}, {"\033[P", 3}, +/* 04-07 */ {"\033[Q", 3}, {"\033[R", 3}, {"\033[S", 3}, {"\033[T", 3}, +/* 08-0B */ {"\033[U", 3}, {"\033[V", 3}, {"\033[W", 3}, {"\033[X", 3}, +/* 0C-0F */ {"\033[W", 3}, {"\033[X", 3}, {"\033[Y", 3}, {"\033[Z", 3}, +/* 10-13 */ {"\033[a", 3}, {"\033[b", 3}, {"\033[c", 3}, {"\033[d", 3}, +/* 14-17 */ {"\033[e", 3}, {"\033[f", 3}, {"\033[g", 3}, {"\033[h", 3}, +/* 18-1B */ {"\033[g", 3}, {"\033[h", 3}, {"\033[i", 3}, {"\033[j", 3}, +/* 1C-1F */ {"\033[k", 3}, {"\033[l", 3}, {"\033[m", 3}, {"\033[n", 3}, +/* 20-23 */ {"\033[o", 3}, {"\033[p", 3}, {"\033[q", 3}, {"\033[r", 3}, +/* 24-27 */ {"\033[g", 3}, {"\033[h", 3}, {"\033[i", 3}, {"\033[j", 3}, +/* 28-2B */ {"\033[k", 3}, {"\033[l", 3}, {"\033[m", 3}, {"\033[n", 3}, +/* 2C-2F */ {"\033[o", 3}, {"\033[p", 3}, {"\033[q", 3}, {"\033[r", 3}, +/* 30-33 */ {"\033[H", 3}, {"\033[A", 3}, {"\033[I", 3}, {"-" , 1}, +/* 34-37 */ {"\033[D", 3}, {"\177" , 1}, {"\033[C", 3}, {"+" , 1}, +/* 38-3B */ {"\033[F", 3}, {"\033[B", 3}, {"\033[G", 3}, {"\033[L", 3} +}; diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c new file mode 100644 index 000000000000..6081c6522bb7 --- /dev/null +++ b/sys/dev/syscons/syscons.c @@ -0,0 +1,2128 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz and Don Ahn. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/* + * Heavily modified by Søren Schmidt (sos@kmd-ac.dk) to provide: + * + * virtual consoles, SYSV ioctl's, ANSI emulation + * + * @(#)syscons.c 0.2 930402 + * + * Modified further to provide full (updated) pccons emulation and + * hooks for init_main.c. Jordan Hubbard, 930725 + * + */ + +#include "param.h" +#include "conf.h" +#include "ioctl.h" +#include "proc.h" +#include "user.h" +#include "tty.h" +#include "uio.h" +#include "callout.h" +#include "systm.h" +#include "kernel.h" +#include "syslog.h" +#include "errno.h" +#include "console.h" +#include "malloc.h" +#include "i386/isa/icu.h" +#include "i386/isa/isa.h" +#include "i386/isa/isa_device.h" +#include "i386/include/pc/display.h" +#include "i386/i386/cons.h" +#include "machine/psl.h" +#include "machine/frame.h" +#include "sc.h" +#include "ddb.h" +#include "iso8859.font" +#include "kbdtables.h" +/*#include "asm.h"*/ + +#if NSC > 0 +#ifndef NCONS +#define NCONS 12 +#endif + +/* status flags */ +#define LOCK_KEY_MASK 0x00007 +#define UNKNOWN_MODE 0x00010 +#define KBD_RAW_MODE 0x00020 +#define SWITCH_WAIT_REL 0x00040 +#define SWITCH_WAIT_ACQ 0x00080 + +/* virtual video memory addresses */ +#define MONO_BUF 0xFE0B0000 +#define CGA_BUF 0xFE0B8000 +#define VGA_BUF 0xFE0A0000 +#define VIDEOMEM 0x000A0000 + +/* misc defines */ +#define MAX_ESC_PAR 2 +#define TEXT80x25 1 +#define TEXT80x50 2 +#define COL 80 +#define ROW 25 +#ifndef XTALSPEED +#define XTALSPEED 1193182 /* should be in isa.h */ +#endif + +/* defines related to hardware addresses */ +#define MONO_BASE 0x3B4 /* crt controller base mono */ +#define COLOR_BASE 0x3D4 /* crt controller base color */ +#define ATC 0x3C0 /* attribute controller */ +#define TSIDX 0x3C4 /* timing sequencer idx */ +#define TSREG 0x3C5 /* timing sequencer data */ +#define PIXMASK 0x3C6 /* pixel write mask */ +#define PALRADR 0x3C7 /* palette read address */ +#define PALWADR 0x3C8 /* palette write address */ +#define PALDATA 0x3C9 /* palette data register */ +#define GDCIDX 0x3CE /* graph data controller idx */ +#define GDCREG 0x3CF /* graph data controller data */ + +typedef struct scr_stat { + u_short *crt_base; /* address of screen memory */ + u_short *scr; /* buffer when off screen */ + u_short *crtat; /* cursor address */ + int esc; /* processing escape sequence */ + int n_par; /* # of parameters to ESC */ + int last_par; /* last parameter # */ + int par[MAX_ESC_PAR]; /* contains ESC parameters */ + int posx; /* current X position */ + int posy; /* current Y position */ + int max_posx; /* X size */ + int max_posy; /* X size */ + int attr; /* current attributes */ + int std_attr; /* normal attributes */ + int rev_attr; /* reverse attributes */ + u_char border; /* border color */ + u_short bell_duration; + u_short bell_pitch; + u_short status; /* status (bitfield) */ + u_short mode; /* mode */ + pid_t pid; /* pid of controlling proc */ + struct proc *proc; /* proc* of controlling proc */ + struct vt_mode smode; /* switch mode */ + } scr_stat; + +static scr_stat cons_scr_stat[NCONS]; +static scr_stat *cur_scr_stat = &cons_scr_stat[0]; +static scr_stat *new_scp, *old_scp; +static int switch_in_progress = 0; + +u_short *Crtat = (u_short *)MONO_BUF; +static u_short *crtat = 0; +static u_int crtc_addr = MONO_BASE; +static u_char shfts = 0, ctls = 0, alts = 0; +static char palette[3*256]; +static const u_int n_fkey_tab = sizeof(fkey_tab) / sizeof(*fkey_tab); +static int cur_cursor_pos = -1; +static char in_putc, nx_scr; +static char saved_console = -1; /* saved console number */ +static long blank_time = 0; /* screen saver timout value */ +static scrmap_t scr_map; + +struct tty pccons[NCONS]; +struct tty *cur_pccons = &pccons[0]; +struct tty *new_pccons; + +extern int hz; +extern struct timeval time; + +#define CSF_ACTIVE 0x1 /* timeout active */ +#define CSF_POLLING 0x2 /* polling for input */ + +struct pcconsoftc { + char cs_flags; + char cs_lastc; /* last char sent */ + int cs_timo; /* timeouts since interrupt */ + u_long cs_wedgecnt; /* times restarted */ + } pcconsoftc = {0, 0, 0, 0}; + + +/* special characters */ +#define bs 8 +#define lf 10 +#define cr 13 +#define cntlc 3 +#define del 0177 +#define cntld 4 + +/* function prototypes */ +int pcprobe(struct isa_device *dev); +int pcattach(struct isa_device *dev); +int pcopen(dev_t dev, int flag, int mode, struct proc *p); +int pcclose(dev_t dev, int flag, int mode, struct proc *p); +int pcread(dev_t dev, struct uio *uio, int flag); +int pcwrite(dev_t dev, struct uio *uio, int flag); +int pcparam(struct tty *tp, struct termios *t); +int pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p); +int pcxint(dev_t dev); +int pcstart(struct tty *tp); +int pccnprobe(struct consdev *cp); +int pccninit(struct consdev *cp); +int pccnputc(dev_t dev, char c); +int pccngetc(dev_t dev); +int scintr(dev_t dev, int irq, int cpl); +void scrn_saver(int test); +static struct tty *get_pccons(dev_t dev); +static scr_stat *get_scr_stat(dev_t dev); +static int get_scr_num(scr_stat *scp); +static void cursor_shape(int start, int end); +static void cursor_pos(void); +static void clear_screen(scr_stat *scp); +static switch_scr(u_int next_scr); +static void exchange_scr(void); +static void move_crsr(scr_stat *scp, u_int x, u_int y); +static void move_up(u_short *s, u_short *d, u_int len); +static void move_down(u_short *s, u_short *d, u_int len); +static void scan_esc(scr_stat *scp, u_char c); +static void ansi_put(scr_stat *scp, u_char c); +void consinit(void); +static void sput(u_char c, u_char ca); +static u_char *get_fstr(u_int c, u_int *len); +static update_leds(int which); +void reset_cpu(void); +u_int sgetc(int noblock); +int pcmmap(dev_t dev, int offset, int nprot); +int getchar(void); +static void kbd_wait(void); +static void kbd_cmd(u_char command); +static void set_mode(scr_stat *scp); +static void set_border(int color); +static load_font(int segment, int size, char* font); +static void save_palette(void); +static void load_palette(void); +static change_winsize(struct tty *tp, int x, int y); + +struct isa_driver scdriver = { + pcprobe, pcattach, "sc", + }; + + +int pcprobe(struct isa_device *dev) +{ + u_char c; + int i, again = 0; + + /* Enable interrupts and keyboard controller */ + kbd_wait(); + outb(KB_STAT, KB_WRITE); + kbd_cmd(0x4D); + + /* Start keyboard stuff RESET */ + kbd_cmd(KB_RESET); + while ((c=inb(KB_DATA)) != KB_ACK) { + if ((c == 0xFE) || (c == 0xFF)) { + if (!again) + printf("KEYBOARD disconnected: RECONNECT \n"); + kbd_cmd(KB_RESET); + again = 1; + } + } + /* + * pick up keyboard reset return code SOS + * some keyboards / controllers hangs if this is enabled + */ + /* while ((c=inb(KB_DATA))!=0xAA); */ + return 1; +} + + +int pcattach(struct isa_device *dev) +{ + scr_stat *scp; + int i; + + if (crtc_addr == MONO_BASE) + printf("VGA mono"); + else + printf("VGA color"); + + if (NCONS > 1) + printf(" <%d virtual consoles>\n", NCONS); + else + printf("\n"); + save_palette(); + load_font(0, 16, font_8x16); + load_font(1, 8, font_8x8); + for (i = 0; i < NCONS; i++) { + scp = &cons_scr_stat[i]; + scp->mode = TEXT80x25; + scp->scr = (u_short *)malloc(COL * ROW * 2, M_DEVBUF, M_NOWAIT); + scp->std_attr = (FG_LIGHTGREY | BG_BLACK) << 8; + scp->rev_attr = (FG_BLACK | BG_LIGHTGREY) << 8; + scp->attr = scp->std_attr; + scp->border = BG_BLACK; + scp->esc = 0; + scp->max_posx = COL; + scp->max_posy = ROW; + scp->bell_pitch = 800; + scp->bell_duration = 10; + scp->status = 0; + scp->pid = 0; + scp->proc = NULL; + scp->smode.mode = VT_AUTO; + if (i > 0) { + scp->crt_base = scp->crtat = scp->scr; + fillw(scp->attr | ' ', scp->scr, COL * ROW); + } + } + cursor_pos(); +} + + +static struct tty *get_pccons(dev_t dev) +{ + int i = minor(dev); + + if (i >= NCONS) + return(NULL); + return(&pccons[i]); +} + + +static scr_stat *get_scr_stat(dev_t dev) +{ + int i = minor(dev); + + if (i >= NCONS) + return(NULL); + return(&cons_scr_stat[i]); +} + + +static int get_scr_num(scr_stat *scp) /* allways call with legal scp !! */ +{ + int i = 0; + + while ((i < NCONS) && (cur_scr_stat != &cons_scr_stat[i])) i++; + return i; +} + +pcopen(dev_t dev, int flag, int mode, struct proc *p) +{ + struct tty *tp = get_pccons(dev); + + if (!tp) + return(ENXIO); + tp->t_oproc = pcstart; + tp->t_param = pcparam; + tp->t_dev = dev; + if ((tp->t_state & TS_ISOPEN) == 0) { + tp->t_state |= TS_WOPEN; + ttychars(tp); + tp->t_iflag = TTYDEF_IFLAG; + tp->t_oflag = TTYDEF_OFLAG; + tp->t_cflag = TTYDEF_CFLAG; + tp->t_lflag = TTYDEF_LFLAG; + tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; + pcparam(tp, &tp->t_termios); + ttsetwater(tp); + } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) + return(EBUSY); + tp->t_state |= TS_CARR_ON; + return((*linesw[tp->t_line].l_open)(dev, tp)); +} + + +pcclose(dev_t dev, int flag, int mode, struct proc *p) +{ + struct tty *tp = get_pccons(dev); + struct scr_stat *scp; + + if (!tp) + return(ENXIO); + scp = get_scr_stat(tp->t_dev); + scp->pid = 0; + scp->proc = NULL; + scp->smode.mode = VT_AUTO; + (*linesw[tp->t_line].l_close)(tp, flag); + ttyclose(tp); + return(0); +} + + +pcread(dev_t dev, struct uio *uio, int flag) +{ + struct tty *tp = get_pccons(dev); + + if (!tp) + return(ENXIO); + return((*linesw[tp->t_line].l_read)(tp, uio, flag)); +} + + +pcwrite(dev_t dev, struct uio *uio, int flag) +{ + struct tty *tp = get_pccons(dev); + + if (!tp) + return(ENXIO); + return((*linesw[tp->t_line].l_write)(tp, uio, flag)); +} + + +/* + * Got a console interrupt, keyboard action ! + * Catch the character, and see who it goes to. + */ +scintr(dev_t dev, int irq, int cpl) +{ + int c, len; + u_char *cp; + + scrn_saver(0); + c = sgetc(1); + if (c & 0x100) + return; + if (pcconsoftc.cs_flags & CSF_POLLING) + return; + if (c < 0x100) + (*linesw[cur_pccons->t_line].l_rint)(c & 0xFF, cur_pccons); + else if (cp = get_fstr((u_int)c, (u_int *)&len)) { + while (len-- > 0) + (*linesw[cur_pccons->t_line].l_rint) + (*cp++ & 0xFF, cur_pccons); + } +} + + +/* + * Set line parameters + */ +pcparam(struct tty *tp, struct termios *t) +{ + int cflag = t->c_cflag; + + /* and copy to tty */ + tp->t_ispeed = t->c_ispeed; + tp->t_ospeed = t->c_ospeed; + tp->t_cflag = cflag; + return(0); +} + + +pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) +{ + int i, error; + struct tty *tp; + struct syscframe *fp; + scr_stat *scp; + + tp = get_pccons(dev); + if (!tp) + return(ENXIO); + scp = get_scr_stat(tp->t_dev); + + switch (cmd) { /* process console hardware related ioctl's */ + + case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */ + blank_time = *(int*)data; + return 0; + + case CONS_80x25TEXT: /* set 80x25 text mode */ + scp->mode = TEXT80x25; + scp->max_posy = 25; + set_mode(scp); + clear_screen(scp); + change_winsize(tp, scp->max_posx, scp->max_posy); + free(scp->scr, M_DEVBUF); + scp->scr = (u_short *)malloc(scp->max_posx*scp->max_posy*2, + M_DEVBUF, M_NOWAIT); + return 0; + + case CONS_80x50TEXT: /* set 80x50 text mode */ + scp->mode = TEXT80x50; + scp->max_posy = 50; + set_mode(scp); + clear_screen(scp); + change_winsize(tp, scp->max_posx, scp->max_posy); + free(scp->scr, M_DEVBUF); + scp->scr = (u_short *)malloc(scp->max_posx*scp->max_posy*2, + M_DEVBUF, M_NOWAIT); + return 0; + + case CONS_GETINFO: /* get current (virtual) console info */ + if (*data == sizeof(struct vid_info)) { + vid_info_t *ptr = (vid_info_t*)data; + ptr->m_num = get_scr_num(scp); + ptr->mv_col = scp->posx; + ptr->mv_row = scp->posy; + ptr->mv_csz = scp->max_posx; + ptr->mv_rsz = scp->max_posy; + ptr->mv_norm.fore = (scp->std_attr & 0x0f00)>>8; + ptr->mv_norm.back = (scp->std_attr & 0xf000)>>12; + ptr->mv_rev.fore = (scp->rev_attr & 0x0f00)>>8; + ptr->mv_rev.back = (scp->rev_attr & 0xf000)>>12; + ptr->mv_grfc.fore = 0; /* not supported */ + ptr->mv_grfc.back = 0; /* not supported */ + ptr->mv_ovscan = scp->border; + ptr->mk_keylock = scp->status & LOCK_KEY_MASK; + return 0; + } + return EINVAL; + + case VT_SETMODE: /* set screen switcher mode */ + bcopy(data, &scp->smode, sizeof(struct vt_mode)); + if (scp->smode.mode == VT_PROCESS) { + scp->proc = p; + scp->pid = scp->proc->p_pid; + } + return 0; + + case VT_GETMODE: /* get screen switcher mode */ + bcopy(&scp->smode, data, sizeof(struct vt_mode)); + return 0; + + case VT_RELDISP: /* screen switcher ioctl */ + switch(*data) { + case VT_FALSE: /* user refuses to release screen, abort */ + if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) { + old_scp->status &= ~SWITCH_WAIT_REL; + switch_in_progress = 0; + return 0; + } + return EINVAL; + + case VT_TRUE: /* user has released screen, go on */ + if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) { + scp->status &= ~SWITCH_WAIT_REL; + exchange_scr(); + if (new_scp->smode.mode == VT_PROCESS) { + new_scp->status |= SWITCH_WAIT_ACQ; + psignal(new_scp->proc, + new_scp->smode.acqsig); + } + else + switch_in_progress = 0; + return 0; + } + return EINVAL; + + case VT_ACKACQ: /* acquire acknowledged, switch completed */ + if (scp == new_scp && (scp->status & SWITCH_WAIT_ACQ)) { + scp->status &= ~SWITCH_WAIT_ACQ; + switch_in_progress = 0; + return 0; + } + return EINVAL; + + default: + return EINVAL; + } + /* NOT REACHED */ + + case VT_OPENQRY: /* return free virtual cons, allways current */ + *data = get_scr_num(scp); + return 0; + + case VT_ACTIVATE: /* switch to screen *data */ + return switch_scr((*data) - 1); + + case VT_WAITACTIVE: /* wait for switch to occur */ + if (*data > NCONS) + return EINVAL; + if (minor(dev) == (*data) - 1) + return 0; + if (*data == 0) { + if (scp == cur_scr_stat) + return 0; + while ((error=tsleep(&scp->smode, + PZERO|PCATCH, "waitvt", 0)) + == ERESTART) ; + } + else + while ((error=tsleep(&cons_scr_stat[*data].smode, + PZERO|PCATCH, "waitvt", 0)) + == ERESTART) ; + return error; + + case KDENABIO: /* allow io operations */ + fp = (struct syscframe *)p->p_regs; + fp->sf_eflags |= PSL_IOPL; + return 0; + + case KDDISABIO: /* disallow io operations (default) */ + fp = (struct syscframe *)p->p_regs; + fp->sf_eflags &= ~PSL_IOPL; + return 0; + + case KDSETMODE: /* set current mode of this (virtual) console */ + switch (*data) { + case KD_TEXT: /* switch to TEXT (known) mode */ + /* restore fonts & palette ! */ + load_font(0, 16, font_8x16); + load_font(1, 8, font_8x8); + load_palette(); + /* FALL THROUGH */ + + case KD_TEXT1: /* switch to TEXT (known) mode */ + /* no restore fonts & palette */ + scp->status &= ~UNKNOWN_MODE; + set_mode(scp); + clear_screen(scp); + return 0; + + case KD_GRAPHICS:/* switch to GRAPHICS (unknown) mode */ + scp->status |= UNKNOWN_MODE; + return 0; + default: + return EINVAL; + } + /* NOT REACHED */ + + case KDGETMODE: /* get current mode of this (virtual) console */ + *data = (scp->status & UNKNOWN_MODE) ? KD_GRAPHICS : KD_TEXT; + return 0; + + case KDSBORDER: /* set border color of this (virtual) console */ + scp->border = *data; + if (scp == cur_scr_stat) + set_border(scp->border); + return 0; + + case KDSKBSTATE: /* set keyboard state (locks) */ + if (*data >= 0 && *data < 4) { + scp->status &= ~LOCK_KEY_MASK; + scp->status |= *data; + if (scp == cur_scr_stat) + update_leds(scp->status & LOCK_KEY_MASK); + return 0; + } + return EINVAL; + + case KDGKBSTATE: /* get keyboard state (locks) */ + *data = scp->status & LOCK_KEY_MASK; + return 0; + + case KDSETRAD: /* set keyboard repeat & delay rates */ + if (*(u_char*)data < 0x80) { + kbd_cmd(KB_SETRAD); + kbd_cmd(*data & 0x7f); + return 0; + } + return EINVAL; + + case KDSKBMODE: /* set keyboard mode */ + switch (*data) { + case K_RAW: /* switch to RAW scancode mode */ + scp->status |= KBD_RAW_MODE; + return 0; + + case K_XLATE: /* switch to XLT ascii mode */ + scp->status &= ~KBD_RAW_MODE; + return 0; + default: + return EINVAL; + } + /* NOT REACHED */ + + case KDGKBMODE: /* get keyboard mode */ + *data = (scp->status & KBD_RAW_MODE) ? K_RAW : K_XLATE; + return 0; + + case KDMKTONE: /* sound the bell */ + if (scp == cur_scr_stat) + sysbeep(scp->bell_pitch, scp->bell_duration); + return 0; + + case KIOCSOUND: /* make tone (*data) hz */ + if (scp == cur_scr_stat) { + if (*(int*)data) { + int pitch = XTALSPEED/(*(int*)data); + /* enable counter 2 */ + outb(0x61, inb(0x61) | 3); + /* set command for counter 2, 2 byte write */ + outb(0x43, 0xb6); + /* set pitch */ + outb(0x42, pitch); + outb(0x42, (pitch>>8)); + } + else { + /* disable counter 2 */ + outb(0x61, inb(0x61) & 0xFC); + } + } + return 0; + + case KDGKBTYPE: /* get keyboard type */ + *data = 0; /* type not known (yet) */ + return 0; + + case KDSETLED: /* set keyboard LED status */ + scp->status &= ~LOCK_KEY_MASK; + scp->status |= (*data & LOCK_KEY_MASK); + if (scp == cur_scr_stat) + update_leds(scp->status & LOCK_KEY_MASK); + return 0; + + case KDGETLED: /* get keyboard LED status */ + *data = scp->status & LOCK_KEY_MASK; + return 0; + + case GETFKEY: /* get functionkey string */ + if (*(u_short*)data < n_fkey_tab) { + fkeyarg_t *ptr = (fkeyarg_t*)data; + bcopy(&fkey_tab[ptr->keynum].str, + ptr->keydef, + fkey_tab[ptr->keynum].len); + ptr->flen = fkey_tab[ptr->keynum].len; + return 0; + } + else + return EINVAL; + + case SETFKEY: /* set functionkey string */ + if (*(u_short*)data < n_fkey_tab) { + fkeyarg_t *ptr = (fkeyarg_t*)data; + bcopy(ptr->keydef, + &fkey_tab[ptr->keynum].str, + min(ptr->flen, MAXFK)); + fkey_tab[ptr->keynum].len = min(ptr->flen, MAXFK); + return 0; + } + else + return EINVAL; + + case GIO_SCRNMAP: /* get output translation table */ + bcopy(&scr_map, data, sizeof(scrmap_t)); + return 0; + + case PIO_SCRNMAP: /* set output translation table */ + bcopy(data, &scr_map, sizeof(scrmap_t)); + return 0; + + case GIO_KEYMAP: /* get keyboard translation table */ + bcopy(&key_map, data, sizeof(key_map)); + return 0; + + case PIO_KEYMAP: /* set keyboard translation table */ + bcopy(data, &key_map, sizeof(key_map)); + return 0; + + case PIO_FONT8x8: /* set 8x8 dot font */ + bcopy(data, &font_8x8, sizeof(fnt8_t)); + load_font(1, 8, font_8x16); + return 0; + + case GIO_FONT8x8: /* get 8x8 dot font */ + bcopy(&font_8x8, data, sizeof(fnt8_t)); + return 0; + + case PIO_FONT8x14: /* set 8x14 dot font */ + bcopy(data, &font_8x14, sizeof(fnt14_t)); + load_font(2, 14, font_8x14); + return 0; + + case GIO_FONT8x14: /* get 8x14 dot font */ + bcopy(&font_8x14, data, sizeof(fnt14_t)); + return 0; + + case PIO_FONT8x16: /* set 8x16 dot font */ + bcopy(data, &font_8x16, sizeof(fnt16_t)); + load_font(0, 16, font_8x16); + return 0; + + case GIO_FONT8x16: /* get 8x16 dot font */ + bcopy(&font_8x16, data, sizeof(fnt16_t)); + return 0; + + case CONSOLE_X_MODE_ON: /* just to be compatible */ + if (saved_console < 0) { + saved_console = get_scr_num(cur_scr_stat); + switch_scr(minor(dev)); + fp = (struct syscframe *)p->p_regs; + fp->sf_eflags |= PSL_IOPL; + scp->status |= UNKNOWN_MODE; + scp->status |= KBD_RAW_MODE; + return 0; + } + return EAGAIN; + + case CONSOLE_X_MODE_OFF:/* just to be compatible */ + fp = (struct syscframe *)p->p_regs; + fp->sf_eflags &= ~PSL_IOPL; + load_font(0, 16, font_8x16); + load_font(1, 8, font_8x8); + scp->status &= ~UNKNOWN_MODE; + set_mode(scp); + clear_screen(scp); + scp->status &= ~KBD_RAW_MODE; + switch_scr(saved_console); + saved_console = -1; + return 0; + + case CONSOLE_X_BELL: + /* + * if set, data is a pointer to a length 2 array of + * integers. data[0] is the pitch in Hz and data[1] + * is the duration in msec. + */ + if (data) + sysbeep(1187500/ ((int*)data)[0], + ((int*)data)[1] * hz/ 3000); + else + sysbeep(0x31b, hz/4); + return 0; + + default: + break; + } + + error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); + if (error >= 0) + return(error); + error = ttioctl(tp, cmd, data, flag); + if (error >= 0) + return(error); + return(ENOTTY); +} + + +pcxint(dev_t dev) +{ + pccons[minor(dev)].t_state &= ~TS_BUSY; + pcconsoftc.cs_timo = 0; + if (pccons[minor(dev)].t_line) + (*linesw[pccons[minor(dev)].t_line].l_start) + (&pccons[minor(dev)]); + else + pcstart(&pccons[minor(dev)]); +} + + +pcstart(struct tty *tp) +{ + int c, s; + scr_stat *scp = get_scr_stat(tp->t_dev); + + s = spltty(); + if (!(tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))) + for (;;) { + if (RB_LEN(&tp->t_out) <= tp->t_lowat) { + if (tp->t_state & TS_ASLEEP) { + tp->t_state &= ~TS_ASLEEP; + wakeup((caddr_t)&tp->t_out); + } + if (tp->t_wsel) { + selwakeup(tp->t_wsel, + tp->t_state & TS_WCOLL); + tp->t_wsel = 0; + tp->t_state &= ~TS_WCOLL; + } + } + if (RB_LEN(&tp->t_out) == 0) + break; + if (scp->status & SLKED) + break; + c = getc(&tp->t_out); + splx(s); + ansi_put(scp, c); + s = spltty(); + } + splx(s); +} + + +pccnprobe(struct consdev *cp) +{ + int maj; + + /* locate the major number */ + for (maj = 0; maj < nchrdev; maj++) + if (cdevsw[maj].d_open == pcopen) + break; + + /* initialize required fields */ + cp->cn_dev = makedev(maj, 0); + cp->cn_tp = &pccons[0]; + cp->cn_pri = CN_INTERNAL; +} + + +pccninit(struct consdev *cp) +{ +} + + +pccnputc(dev_t dev, char c) +{ + int pos; + + if (cur_scr_stat->status & UNKNOWN_MODE) + return; + if (c == '\n') + sput('\r', FG_LIGHTGREY | BG_BLACK); + sput(c, FG_LIGHTGREY | BG_BLACK); + pos = cur_scr_stat->crtat - cur_scr_stat->crt_base; + if (pos != cur_cursor_pos) { + cur_cursor_pos = pos; + outb(crtc_addr,14); + outb(crtc_addr+1,pos >> 8); + outb(crtc_addr,15); + outb(crtc_addr+1,pos&0xff); + } +} + + +pccngetc(dev_t dev) +{ + int c, s; + + s = spltty(); /* block scintr while we poll */ + c = sgetc(0); + splx(s); + if (c == '\r') c = '\n'; + return(c); +} + +#ifndef DONT_BLANK + +void scrn_saver(int test) +{ + u_char val; + static int blanked = 0; + static long time_stamp; + + if (test && blank_time) { + if (time.tv_sec > time_stamp + blank_time) { + blanked = 1; + outb(TSIDX, 0x01); val = inb(TSREG); + outb(TSIDX, 0x01); outb(TSREG, val | 0x20); + } + } + else { + time_stamp = time.tv_sec; + if (blanked) { + blanked = 0; + outb(TSIDX, 0x01); val = inb(TSREG); + outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); + } + } +} + +#else +/* + * alternative screen saver for cards that do not like blanking + * donated by Christoph Robitchko + */ +static u_short cur_cursor_shape; /* remember cursor shape */ + +void scrn_saver(int test) +{ + const char saves[] = {"386BSD"}; + static int blanked = 0; + static u_char *savs[sizeof(saves)-1]; + static int dirx, diry; + static long time_stamp; + static u_short save_cursor; + int f; + scr_stat *scp = cur_scr_stat; + + if (test && blank_time) { + if (time.tv_sec > time_stamp + blank_time) { + if (!blanked) { + bcopy(Crtat, scp->scr, + scp->max_posx * scp->max_posy * 2); + fillw(0x07<<8 | ' ', Crtat, + scp->max_posx * scp->max_posy); + set_border(0); + dirx = (scp->posx ? 1 : -1); + diry = (scp->posy ? + scp->max_posx : -scp->max_posx); + for (f=0; f< sizeof(saves)-1; f++) + savs[f] = (u_char *)Crtat + 2 * + (scp->posx+scp->posy*scp->max_posx); + *(savs[0]) = *saves; + f = scp->max_posy * scp->max_posx + 5; + outb(crtc_addr, 14); + outb(crtc_addr+1, f >> 8); + outb(crtc_addr, 15); + outb(crtc_addr+1, f & 0xff); + save_cursor = cur_cursor_shape; + blanked = 1; + } + if (blanked++ < 4) + return; + blanked = 1; + *(savs[sizeof(saves)-2]) = ' '; + for (f=sizeof(saves)-2; f > 0; f--) + savs[f] = savs[f-1]; + f = (savs[0] - (u_char *)Crtat) / 2; + if ((f % scp->max_posx) == 0 || + (f % scp->max_posx) == scp->max_posx - 1) + dirx = -dirx; + if ((f / scp->max_posx) == 0 || + (f / scp->max_posx) == scp->max_posy - 1) + diry = -diry; + savs[0] += 2*dirx + 2*diry; + for (f=sizeof(saves)-2; f>=0; f--) + *(savs[f]) = saves[f]; + } + } + else { + time_stamp = time.tv_sec; + if (blanked) { + bcopy(scp->scr, Crtat, + scp->max_posx * scp->max_posy * 2); + cur_cursor_pos = -1; + cursor_shape((save_cursor >> 8) & 0xff, + save_cursor & 0xff); + set_border(scp->border); + blanked = 0; + } + } +} + +#endif /* DONT_BLANK */ + +static void cursor_shape(int start, int end) +{ + outb(crtc_addr, 10); + outb(crtc_addr+1, start & 0xFF); + outb(crtc_addr, 11); + outb(crtc_addr+1, end & 0xFF); +#ifdef DONT_BLANK + cur_cursor_shape = ((start & 0xff) << 8) | (end & 0xff); +#endif +} + + +static void cursor_pos(void) +{ + int pos = cur_scr_stat->crtat - cur_scr_stat->crt_base; + + if (cur_scr_stat->status & UNKNOWN_MODE) + return; + scrn_saver(1); + if (pos != cur_cursor_pos) { + cur_cursor_pos = pos; + outb(crtc_addr,14); + outb(crtc_addr+1,pos >> 8); + outb(crtc_addr,15); + outb(crtc_addr+1,pos&0xff); + } + timeout(cursor_pos,0,hz/20); +} + + +static void clear_screen(scr_stat *scp) +{ + move_crsr(scp, 0, 0); + fillw(scp->attr | ' ', scp->crt_base, + scp->max_posx * scp->max_posy); +} + + +static switch_scr(u_int next_scr) +{ + if (in_putc) { /* don't switch if in putc */ + nx_scr = next_scr + 1; + return 0; + } + if (next_scr >= NCONS || switch_in_progress) { + sysbeep(800, hz/4); + return -1; + } + switch_in_progress = 1; + old_scp = cur_scr_stat; + new_scp = &cons_scr_stat[next_scr]; + wakeup(&new_scp->smode); + if (new_scp == old_scp) { + switch_in_progress = 0; + return 0; + } + new_pccons = &pccons[next_scr]; + + /* has controlling process died? */ + if (old_scp->proc && (old_scp->proc != pfind(old_scp->pid))) + old_scp->smode.mode = VT_AUTO; + if (new_scp->proc && (new_scp->proc != pfind(new_scp->pid))) + new_scp->smode.mode = VT_AUTO; + + /* check the modes and switch approbiatly */ + if (old_scp->smode.mode == VT_PROCESS) { + old_scp->status |= SWITCH_WAIT_REL; + psignal(old_scp->proc, old_scp->smode.relsig); + } + else { + exchange_scr(); + if (new_scp->smode.mode == VT_PROCESS) { + new_scp->status |= SWITCH_WAIT_ACQ; + psignal(new_scp->proc, new_scp->smode.acqsig); + } + else + switch_in_progress = 0; + } + return 0; +} + + +static void exchange_scr(void) +{ + bcopy(Crtat, old_scp->scr, old_scp->max_posx * old_scp->max_posy * 2); + old_scp->crt_base = old_scp->scr; + move_crsr(old_scp, old_scp->posx, old_scp->posy); + cur_scr_stat = new_scp; + cur_pccons = new_pccons; + if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE) + shfts = ctls = alts = 0; + update_leds(new_scp->status & LOCK_KEY_MASK); + set_mode(new_scp); + new_scp->crt_base = Crtat; + move_crsr(new_scp, new_scp->posx, new_scp->posy); + bcopy(new_scp->scr, Crtat, new_scp->max_posx * new_scp->max_posy * 2); + nx_scr = 0; +} + + +static void move_crsr(scr_stat *scp, u_int x, u_int y) +{ + if (x < 0 || y < 0 || x >= scp->max_posx || y >= scp->max_posy) + return; + scp->posx = x; + scp->posy = y; + scp->crtat = scp->crt_base + scp->posy * scp->max_posx + scp->posx; +} + + +static void move_up(u_short *s, u_short *d, u_int len) +{ + s += len; + d += len; + while (len-- > 0) + *--d = *--s; +} + + +static void move_down(u_short *s, u_short *d, u_int len) +{ + while (len-- > 0) + *d++ = *s++; +} + + +static void scan_esc(scr_stat *scp, u_char c) +{ + static u_char ansi_col[16] = + {0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15}; + int i, n, m; + u_short *src, *dst, count; + + if (scp->esc == 1) { + switch (c) { + + case '[': /* Start ESC [ sequence */ + scp->esc = 2; + scp->last_par = -1; + for (i = scp->n_par; i < MAX_ESC_PAR; i++) + scp->par[i] = 1; + scp->n_par = 0; + return; + + case 'M': /* Move cursor up 1 line, scroll if at top */ + if (scp->posy > 0) + move_crsr(scp, scp->posx, scp->posy - 1); + else { + move_up(scp->crt_base, + scp->crt_base + scp->max_posx, + (scp->max_posy - 1) * scp->max_posx); + fillw(scp->attr | ' ', + scp->crt_base, scp->max_posx); + } + break; +#if notyet + case 'Q': + scp->esc = 4; + break; +#endif + case 'c': /* Clear screen & home */ + clear_screen(scp); + break; + } + } + else if (scp->esc == 2) { + if (c >= '0' && c <= '9') { + if (scp->n_par < MAX_ESC_PAR) { + if (scp->last_par != scp->n_par) { + scp->last_par = scp->n_par; + scp->par[scp->n_par] = 0; + } + else + scp->par[scp->n_par] *= 10; + scp->par[scp->n_par] += c - '0'; + return; + } + } + scp->n_par = scp->last_par + 1; + switch (c) { + + case ';': + if (scp->n_par < MAX_ESC_PAR) + return; + break; + + case '=': + scp->esc = 3; + scp->last_par = -1; + for (i = scp->n_par; i < MAX_ESC_PAR; i++) + scp->par[i] = 1; + scp->n_par = 0; + return; + + case 'A': /* up n rows */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx, scp->posy - n); + break; + + case 'B': /* down n rows */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx, scp->posy + n); + break; + + case 'C': /* right n columns */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx + n, scp->posy); + break; + + case 'D': /* left n columns */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx - n, scp->posy); + break; + + case 'E': /* cursor to start of line n lines down */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, 0, scp->posy + n); + break; + + case 'F': /* cursor to start of line n lines up */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, 0, scp->posy - n); + break; + + case 'f': /* System V consoles .. */ + case 'H': /* Cursor move */ + if (scp->n_par == 0) + move_crsr(scp, 0, 0); + else if (scp->n_par == 2) + move_crsr(scp, scp->par[1] - 1, scp->par[0] - 1); + break; + + case 'J': /* Clear all or part of display */ + if (scp->n_par == 0) + n = 0; + else + n = scp->par[0]; + switch (n) { + case 0: /* clear form cursor to end of display */ + fillw(scp->attr | ' ', scp->crtat, + scp->crt_base + scp->max_posx * + scp->max_posy - scp->crtat); + break; + case 1: /* clear from beginning of display to cursor */ + fillw(scp->attr | ' ', scp->crt_base, + scp->crtat - scp->crt_base); + break; + case 2: /* clear entire display */ + clear_screen(scp); + break; + } + break; + + case 'K': /* Clear all or part of line */ + if (scp->n_par == 0) + n = 0; + else + n = scp->par[0]; + switch (n) { + case 0: /* clear form cursor to end of line */ + fillw(scp->attr | ' ', scp->crtat, + scp->max_posx - scp->posx); + break; + case 1: /* clear from beginning of line to cursor */ + fillw(scp->attr | ' ', + scp->crtat - (scp->max_posx - scp->posx), + (scp->max_posx - scp->posx) + 1); + break; + case 2: /* clear entire line */ + fillw(scp->attr | ' ', + scp->crtat - (scp->max_posx - scp->posx), + scp->max_posx); + break; + } + break; + + case 'L': /* Insert n lines */ + n = scp->par[0]; if (n < 1) n = 1; + if (n > scp->max_posy - scp->posy) + n = scp->max_posy - scp->posy; + src = scp->crt_base + scp->posy * scp->max_posx; + dst = src + n * scp->max_posx; + count = scp->max_posy - (scp->posy + n); + move_up(src, dst, count * scp->max_posx); + fillw(scp->attr | ' ', src, n * scp->max_posx); + break; + + case 'M': /* Delete n lines */ + n = scp->par[0]; if (n < 1) n = 1; + if (n > scp->max_posy - scp->posy) + n = scp->max_posy - scp->posy; + dst = scp->crt_base + scp->posy * scp->max_posx; + src = dst + n * scp->max_posx; + count = scp->max_posy - (scp->posy + n); + move_down(src, dst, count * scp->max_posx); + src = dst + count * scp->max_posx; + fillw(scp->attr | ' ', src, n * scp->max_posx); + break; + + case 'P': /* Delete n chars */ + n = scp->par[0]; if (n < 1) n = 1; + if (n > scp->max_posx - scp->posx) + n = scp->max_posx - scp->posx; + dst = scp->crtat; + src = dst + n; + count = scp->max_posx - (scp->posx + n); + move_down(src, dst, count); + src = dst + count; + fillw(scp->attr | ' ', src, n); + break; + + case '@': /* Insert n chars */ + n = scp->par[0]; if (n < 1) n = 1; + if (n > scp->max_posx - scp->posx) + n = scp->max_posx - scp->posx; + src = scp->crtat; + dst = src + n; + count = scp->max_posx - (scp->posx + n); + move_up(src, dst, count); + fillw(scp->attr | ' ', src, n); + break; + + case 'S': /* scroll up n lines */ + n = scp->par[0]; if (n < 1) n = 1; + bcopy(scp->crt_base + (scp->max_posx * n), + scp->crt_base, + scp->max_posx * (scp->max_posy - n) * + sizeof(u_short)); + fillw(scp->attr | ' ', + scp->crt_base + scp->max_posx * + (scp->max_posy - 1), + scp->max_posx); + break; + + case 'T': /* scroll down n lines */ + n = scp->par[0]; if (n < 1) n = 1; + bcopy(scp->crt_base, + scp->crt_base + (scp->max_posx * n), + scp->max_posx * (scp->max_posy - n) * + sizeof(u_short)); + fillw(scp->attr | ' ', scp->crt_base, scp->max_posx); + break; + + case 'X': /* delete n characters in line */ + n = scp->par[0]; if (n < 1) n = 1; + fillw(scp->attr | ' ', scp->crt_base + scp->posx + + ((scp->max_posx*scp->posy) * sizeof(u_short)), n); + break; + + case 'Z': /* move n tabs backwards */ + n = scp->par[0]; if (n < 1) n = 1; + if ((i = scp->posx & 0xf8) == scp->posx) + i -= 8*n; + else + i -= 8*(n-1); + if (i < 0) + i = 0; + move_crsr(scp, i, scp->posy); + break; + + case '`': /* move cursor to column n */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, n, scp->posy); + break; + + case 'a': /* move cursor n columns to the right */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx + n, scp->posy); + break; + + case 'd': /* move cursor to row n */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx, n); + break; + + case 'e': /* move cursor n rows down */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx, scp->posy + n); + break; + + case 'm': /* change attribute */ + if (scp->n_par == 0) + n = 0; + else + n = scp->par[0]; + switch (n) { + case 0: /* back to normal */ + scp->attr = scp->std_attr; + break; + case 1: /* highlight (bold) */ + scp->attr &= 0xFF00; + scp->attr |= 0x0800; + break; + case 4: /* highlight (underline) */ + scp->attr &= 0x0F00; + scp->attr |= 0x0800; + break; + case 5: /* blink */ + scp->attr &= 0xFF00; + scp->attr |= 0x8000; + break; + case 7: /* reverse video */ + scp->attr = scp->rev_attr; + break; + case 30: case 31: case 32: case 33: /* set fg color */ + case 34: case 35: case 36: case 37: + scp->attr = (scp->attr & 0xF0FF) + | (ansi_col[(n - 30) & 7] << 8); + break; + case 40: case 41: case 42: case 43: /* set bg color */ + case 44: case 45: case 46: case 47: + scp->attr = (scp->attr & 0x0FFF) + | (ansi_col[(n - 40) & 7] << 12); + break; + } + break; + + case 'x': + if (scp->n_par == 0) + n = 0; + else + n = scp->par[0]; + switch (n) { + case 0: /* reset attributes */ + scp->attr = scp->std_attr = FG_LIGHTGREY << 8; + break; + case 1: /* set ansi background */ + scp->attr = scp->std_attr = + (scp->std_attr & 0x0F00) + | (ansi_col[(scp->par[1])&0x0F] << 12); + break; + case 2: /* set ansi foreground */ + scp->attr = scp->std_attr = + (scp->std_attr & 0xF000) + | (ansi_col[(scp->par[1])&0x0F] << 8); + break; + case 3: /* set ansi attribute directly */ + scp->attr = scp->std_attr = + (scp->par[1] & 0xFF) << 8; + break; + case 5: /* set ansi reverse video background */ + scp->rev_attr = + (scp->rev_attr & 0x0F00) + | (ansi_col[(scp->par[1]) & 0x0F] << 12); + break; + case 6: /* set ansi reverse video foreground */ + scp->rev_attr = + (scp->rev_attr & 0xF000) + | (ansi_col[(scp->par[1]) & 0x0F] << 8); + break; + case 7: /* set ansi reverse video directly */ + scp->rev_attr = (scp->par[1] & 0xFF) << 8; + break; + } + break; + + case 'z': /* switch to (virtual) console n */ + if (scp->n_par == 1) + switch_scr(scp->par[0]); + break; + } + } + else if (scp->esc == 3) { + if (c >= '0' && c <= '9') { + if (scp->n_par < MAX_ESC_PAR) { + if (scp->last_par != scp->n_par) { + scp->last_par = scp->n_par; + scp->par[scp->n_par] = 0; + } + else + scp->par[scp->n_par] *= 10; + scp->par[scp->n_par] += c - '0'; + return; + } + } + scp->n_par = scp->last_par + 1; + switch (c) { + + case ';': + if (scp->n_par < MAX_ESC_PAR) + return; + break; + + case 'A': /* set display border color */ + if (scp->n_par == 1) + scp->border=scp->par[0] & 0xff; + if (scp == cur_scr_stat) + set_border(scp->border); + break; + + case 'B': /* set bell pitch and duration */ + if (scp->n_par == 2) { + scp->bell_pitch = scp->par[0]; + scp->bell_duration = scp->par[1]*10; + } + break; + + case 'C': /* set cursor shape (start & end line) */ + if (scp->n_par == 2) + cursor_shape(scp->par[0], scp->par[1]); + break; + + case 'F': /* set ansi foreground */ + if (scp->n_par == 1) + scp->attr = scp->std_attr = + (scp->std_attr & 0xF000) + | ((scp->par[0] & 0x0F) << 8); + break; + + case 'G': /* set ansi background */ + if (scp->n_par == 1) + scp->attr = scp->std_attr = + (scp->std_attr & 0x0F00) + | ((scp->par[0] & 0x0F) << 12); + break; + + case 'H': /* set ansi reverse video foreground */ + if (scp->n_par == 1) + scp->rev_attr = + (scp->rev_attr & 0xF000) + | ((scp->par[0] & 0x0F) << 8); + break; + + case 'I': /* set ansi reverse video background */ + if (scp->n_par == 1) + scp->rev_attr = + (scp->rev_attr & 0x0F00) + | ((scp->par[0] & 0x0F) << 12); + break; + } + } + scp->esc = 0; +} + + +#define wrtchar(scp, c) ( *scp->crtat = (c), scp->crtat++, scp->posx++ ) + +static void ansi_put(scr_stat *scp, u_char c) +{ + int s; + + if (scp == cur_scr_stat ) + scrn_saver(0); + if (scp->status & UNKNOWN_MODE) + return; + in_putc++; + if (scp->esc) + scan_esc(scp, c); + else switch(c) { + case 0x1B: + scp->esc = 1; + scp->n_par = 0; + break; + case '\t': + do { + wrtchar(scp, scp->attr | ' '); + } while (scp->posx % 8); + break; + case '\b': /* non-destructive backspace */ + if (scp->crtat > scp->crt_base) { + scp->crtat--; + if (scp->posx > 0) + scp->posx--; + else { + scp->posx += scp->max_posx - 1; + scp->posy--; + } + } + break; + case '\r': + move_crsr(scp, 0, scp->posy); + break; + case '\n': + scp->crtat += scp->max_posx; + scp->posy++; + break; + case '\f': + clear_screen(scp); + break; + default: + if (c == 7) { + if (scp == cur_scr_stat) + sysbeep(scp->bell_pitch, scp->bell_duration); + } + /* Print only printables */ + else { + wrtchar(scp, scp->attr | c); + if (scp->posx >= scp->max_posx) { + scp->posx = 0; + scp->posy++; + } + break; + } + } + if (scp->crtat >= scp->crt_base + scp->max_posy * scp->max_posx) { + bcopy(scp->crt_base + scp->max_posx, scp->crt_base, + scp->max_posx * (scp->max_posy - 1) * sizeof(u_short)); + fillw(scp->attr | ' ', + scp->crt_base + scp->max_posx * (scp->max_posy - 1), + scp->max_posx); + scp->crtat -= scp->max_posx; + scp->posy--; + } + s = spltty(); + in_putc--; + splx(s); + if (nx_scr) + switch_scr(nx_scr - 1); +} + + +void consinit(void) +{ + u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/sizeof(u_short), was; + scr_stat *scp; + unsigned cursorat; + int i; + + /* + * catch that once in a blue moon occurence when consinit is called + * TWICE, adding the CGA_BUF offset again -> poooff + * thanks to Christoph Robitchko for finding this one !! + */ + if (crtat != 0) + return; + /* + * Crtat initialized to point to MONO buffer, if not present change + * to CGA_BUF offset. ONLY ADD the difference since locore.s adds + * in the remapped offset at the right time + */ + was = *cp; + *cp = (u_short) 0xA55A; + if (*cp != 0xA55A) { + crtc_addr = MONO_BASE; + } else { + *cp = was; + crtc_addr = COLOR_BASE; + Crtat = Crtat + (CGA_BUF-MONO_BUF)/sizeof(u_short); + } + /* Extract cursor location */ + outb(crtc_addr,14); + cursorat = inb(crtc_addr+1)<<8 ; + outb(crtc_addr,15); + cursorat |= inb(crtc_addr+1); + + crtat = Crtat+ cursorat; + + cons_scr_stat[0].crtat = crtat; + cons_scr_stat[0].crt_base = Crtat; + cons_scr_stat[0].posx = cursorat % COL; + cons_scr_stat[0].posy = cursorat / COL; + cons_scr_stat[0].esc = 0; + cons_scr_stat[0].std_attr = (FG_LIGHTGREY | BG_BLACK) << 8; + cons_scr_stat[0].rev_attr = (FG_BLACK | BG_LIGHTGREY) << 8; + cons_scr_stat[0].attr = (FG_LIGHTGREY | BG_BLACK) << 8; + cons_scr_stat[0].border = BG_BLACK;; + cons_scr_stat[0].max_posx = COL; + cons_scr_stat[0].max_posy = ROW; + cons_scr_stat[0].status = 0; + cons_scr_stat[0].pid = 0; + cons_scr_stat[0].proc = NULL; + cons_scr_stat[0].smode.mode = VT_AUTO; + cons_scr_stat[0].bell_pitch = 800; + cons_scr_stat[0].bell_duration = 10; + clear_screen(&cons_scr_stat[0]); +} + + +static void sput(u_char c, u_char ca) +{ + int i; + scr_stat *scp = &cons_scr_stat[0]; + + if (crtat == 0) + consinit(); + i = scp->attr; + scp->attr = ca << 8; + ansi_put(scp, c); + scp->attr = i; +} + + +static u_char *get_fstr(u_int c, u_int *len) +{ + u_int i; + + if (!(c & FKEY)) + return(NULL); + i = (c & 0xFF) - F_FN; + if (i > n_fkey_tab) + return(NULL); + *len = fkey_tab[i].len; + return(fkey_tab[i].str); +} + + +static update_leds(int which) +{ + u_char xlate_leds[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; + int i; + + kbd_cmd(KB_SETLEDS); /* LED Command */ + kbd_cmd(xlate_leds[which]); + kbd_wait(); +} + + +volatile void reset_cpu(void) +{ + int i; + + while (1) { + kbd_cmd(KB_RESET_CPU); /* Reset Command */ + DELAY(4000000); + kbd_cmd(KB_RESET); /* Keyboard Reset Command */ + } +} + + +/* + * sgetc(noblock) : get a character from the keyboard. + * If noblock = 0 wait until a key is gotten. Otherwise return a 0x100. + */ +u_int sgetc(int noblock) +{ + u_char dt, modifier; + static u_char esc_flag = 0; + u_int state, action; + int i; + struct key_t *key; + +next_code: + kbd_wait(); + /* First see if there is something in the keyboard port */ + if (inb(KB_STAT) & KB_BUF_FULL) + dt = inb(KB_DATA); + else if (noblock) + return(0x100); + else + goto next_code; + + if (cur_scr_stat->status & KBD_RAW_MODE) + return dt; + + /* Check for cntl-alt-del */ + if ((dt == 83) && ctls && alts) + cpu_reset(); + +#if NDDB > 0 + /* Check for cntl-alt-esc */ + if ((dt == 1) && ctls && alts) { + /* if debugger called, try to switch to console 0 */ + if (cur_scr_stat->smode.mode == VT_AUTO && + cons_scr_stat[0].smode.mode == VT_AUTO) + switch_scr(0); + Debugger(); + } +#endif + if (dt == 0xE0 || dt == 0xE1) { + esc_flag = dt; + goto next_code; + } + + if ((dt & 0x7F) >= key_map.n_keys) + goto next_code; + + if (esc_flag == 0xE0) { + switch (dt & 0x7F) { + case 0x2A: /* This may come because the keyboard keeps */ + case 0x36: /* its own caps lock status, we ignore SOS */ + goto next_code; + /* NOT REACHED */ + case 0x1C: /* keypad enter key */ + modifier = 0x59; + break; + case 0x1D: /* right control key */ + modifier = 0x5a; + break; + case 0x35: /* keypad divide key */ + modifier = 0x5b; + break; + case 0x37: /* print scrn key */ + modifier = 0x5c; + break; + case 0x38: /* right alt key (alt gr) */ + modifier = 0x5d; + break; + case 0x47: /* grey home key */ + modifier = 0x5e; + break; + case 0x48: /* grey up arrow key */ + modifier = 0x5f; + break; + case 0x49: /* grey page up key */ + modifier = 0x60; + break; + case 0x4b: /* grey left arrow key */ + modifier = 0x61; + break; + case 0x4d: /* grey right arrow key */ + modifier = 0x62; + break; + case 0x4f: /* grey end key */ + modifier = 0x63; + break; + case 0x50: /* grey down arrow key */ + modifier = 0x64; + break; + case 0x51: /* grey page down key */ + modifier = 0x65; + break; + case 0x52: /* grey insert key */ + modifier = 0x66; + break; + case 0x53: /* grey delete key */ + modifier = 0x67; + break; + default: /* every thing else is ignored */ + goto next_code; + /* NOT REACHED */ + } + dt = (dt & 0x80) | modifier; + } + else if (esc_flag == (u_char)0xE1 && ((dt & 0x7F) == 0x1D)) { + esc_flag = 0x1D; + goto next_code; + } + else if (esc_flag == 0x1D && ((dt & 0x7F) == 0x45)) + dt = (dt & 0x80) | 0x68; + esc_flag = 0; + + state = (shfts ? 1 : 0 ) | (2 * (ctls ? 1 : 0)) | (4 * (alts ? 1 : 0)); + key = &key_map.key[dt & 0x7F]; + if ( ((key->flgs & FLAG_LOCK_C) && (cur_scr_stat->status & CLKED)) + || ((key->flgs & FLAG_LOCK_N) && (cur_scr_stat->status & NLKED)) ) + state ^= 1; + + /* Check for make/break */ + action = key->map[state]; + if (dt & 0x80) { + /* break */ + if (key->spcl & 0x80) { + switch (action) { + case LSH: + shfts &= ~1; + break; + case RSH: + shfts &= ~2; + break; + case LCTR: + ctls &= ~1; + break; + case RCTR: + ctls &= ~2; + break; + case LALT: + alts &= ~1; + break; + case RALT: + alts &= ~2; + break; + } + } + } else { + /* make */ + if (key->spcl & (0x80>>state)) { + switch (action) { + /* LOCKING KEYS */ + case NLK: + if (cur_scr_stat->status & NLKED) + cur_scr_stat->status &= ~NLKED; + else + cur_scr_stat->status |= NLKED; + update_leds(cur_scr_stat->status&LOCK_KEY_MASK); + break; + case CLK: + if (cur_scr_stat->status & CLKED) + cur_scr_stat->status &= ~CLKED; + else + cur_scr_stat->status |= CLKED; + update_leds(cur_scr_stat->status&LOCK_KEY_MASK); + break; + case SLK: + if (cur_scr_stat->status & SLKED) { + cur_scr_stat->status &= ~SLKED; + pcstart(&pccons[get_scr_num(cur_scr_stat)]); + } + else + cur_scr_stat->status |= SLKED; + update_leds(cur_scr_stat->status&LOCK_KEY_MASK); + break; + + /* NON-LOCKING KEYS */ + case LSH: + shfts |= 1; + break; + case RSH: + shfts |= 2; + break; + case LCTR: + ctls |= 1; + break; + case RCTR: + ctls |= 2; + break; + case LALT: + alts |= 1; + break; + case RALT: + alts |= 2; + break; + default: + if (action >= F_SCR && action <= L_SCR) { + switch_scr(action - F_SCR); + break; + } + if (action >= F_FN && action <= L_FN) { + return(action | FKEY); + } + return(action); + } + } + else return(action); + } + goto next_code; +} + +/* -hv- 22-Apr-93: to make init_main more portable */ +void cons_highlight(void) +{ + scr_stat *scp = &cons_scr_stat[0]; + + scp->attr &= 0xFF00; + scp->attr |= 0x0800; +} + +void cons_normal(void) +{ + scr_stat *scp = &cons_scr_stat[0]; + + scp->attr = scp->std_attr; +} + +int getchar(void) +{ + char thechar; + int delay, x; + + pcconsoftc.cs_flags |= CSF_POLLING; + x = splhigh(); + sput('>', FG_RED | BG_BLACK); + thechar = (char) sgetc(0); + pcconsoftc.cs_flags &= ~CSF_POLLING; + splx(x); + switch (thechar) { + default: + if (thechar >= ' ') + sput(thechar, FG_RED | BG_BLACK); + return(thechar); + case cr: + case lf: + sput(cr, FG_RED | BG_BLACK); + sput(lf, FG_RED | BG_BLACK); + return(lf); + case bs: + case del: + sput(bs, FG_RED | BG_BLACK); + sput(' ', FG_RED | BG_BLACK); + sput(bs, FG_RED | BG_BLACK); + return(thechar); + case cntld: + sput('^', FG_RED | BG_BLACK) ; + sput('D', FG_RED | BG_BLACK) ; + sput('\r', FG_RED | BG_BLACK) ; + sput('\n', FG_RED | BG_BLACK) ; + return(0); + } +} + + +int pcmmap(dev_t dev, int offset, int nprot) +{ + if (offset > 0x20000) + return EINVAL; + return i386_btop((VIDEOMEM + offset)); +} + + +static void kbd_wait(void) +{ + int i; + for (i=0; i<10000; i++) + if ((inb(KB_STAT) & KB_READY) == 0) + break; +} + + +static void kbd_cmd(u_char command) +{ + kbd_wait(); + outb(KB_DATA, command); +} + + +static void set_mode(scr_stat *scp) +{ + u_char byte; + + if (scp != cur_scr_stat) + return; + + /* setup video hardware for the given mode */ + switch(scp->mode) { + case TEXT80x25: + outb(crtc_addr, 9); byte = inb(crtc_addr+1); + outb(crtc_addr, 9); outb(crtc_addr+1, byte | 0x0F); + outb(TSIDX, 0x03); outb(TSREG, 0x00); /* select font 0 */ + break; + case TEXT80x50: + outb(crtc_addr, 9); byte = inb(crtc_addr+1); + outb(crtc_addr, 9); outb(crtc_addr+1, (byte & 0xF0) | 0x07); + outb(TSIDX, 0x03); outb(TSREG, 0x05); /* select font 1 */ + break; + default: + return; + } + + /* set border color for this (virtual) console */ + set_border(scp->border); + + /* (re)activate cursor */ + untimeout(cursor_pos, 0); + cursor_pos(); +} + + +static void set_border(int color) +{ + inb(crtc_addr+6); /* reset flip-flop */ + outb(ATC, 0x11); outb(ATC, color); + inb(crtc_addr+6); /* reset flip-flop */ + outb(ATC, 0x20); /* enable Palette */ +} + +static load_font(int segment, int size, char* font) +{ + int ch, line; + u_char val; + + outb(TSIDX, 0x01); val = inb(TSREG); /* blank screen */ + outb(TSIDX, 0x01); outb(TSREG, val | 0x20); + + /* setup vga for loading fonts (graphics plane mode) */ + inb(crtc_addr+6); /* reset flip/flop */ + outb(ATC, 0x30); outb(ATC, 0x01); + outb(TSIDX, 0x02); outb(TSREG, 0x04); + outb(TSIDX, 0x04); outb(TSREG, 0x06); + outb(GDCIDX, 0x04); outb(GDCREG, 0x02); + outb(GDCIDX, 0x05); outb(GDCREG, 0x00); + outb(GDCIDX, 0x06); outb(GDCREG, 0x05); /* addr = a0000, 64kb */ + for (ch=0; ch < 256; ch++) + for (line=0; line < size; line++) + *((char *)atdevbase+(segment*0x4000)+(ch*32)+line) = + font[(ch*size)+line]; + /* setup vga for text mode again */ + inb(crtc_addr+6); /* reset flip/flop */ + outb(ATC, 0x30); outb(ATC, 0x0C); + outb(TSIDX, 0x02); outb(TSREG, 0x03); + outb(TSIDX, 0x04); outb(TSREG, 0x02); + outb(GDCIDX, 0x04); outb(GDCREG, 0x00); + outb(GDCIDX, 0x05); outb(GDCREG, 0x10); + if (crtc_addr == MONO_BASE) { + outb(GDCIDX, 0x06); outb(GDCREG, 0x0A); /* addr = b0000, 32kb */ + } + else { + outb(GDCIDX, 0x06); outb(GDCREG, 0x0E); /* addr = b8000, 32kb */ + } + outb(TSIDX, 0x01); val = inb(TSREG); /* unblank screen */ + outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); +} + + +static void load_palette(void) +{ + int i; + + outb(PIXMASK, 0xFF); /* no pixelmask */ + outb(PALWADR, 0x00); + for (i=0x00; i<0x300; i++) + outb(PALDATA, palette[i]); + inb(crtc_addr+6); /* reset flip/flop */ + outb(ATC, 0x20); /* enable palette */ +} + +static void save_palette(void) +{ + int i; + + outb(PALRADR, 0x00); + for (i=0x00; i<0x300; i++) + palette[i] = inb(PALDATA); + inb(crtc_addr+6); /* reset flip/flop */ +} + + +static change_winsize(struct tty *tp, int x, int y) +{ + if (tp->t_winsize.ws_col != x || tp->t_winsize.ws_row != y) { + tp->t_winsize.ws_col = x; + tp->t_winsize.ws_row = y; + pgsignal(tp->t_pgrp, SIGWINCH, 1); + } +} + +#endif /* NSC */ diff --git a/sys/i386/isa/iso8859.font b/sys/i386/isa/iso8859.font new file mode 100644 index 000000000000..869615e4e7fb --- /dev/null +++ b/sys/i386/isa/iso8859.font @@ -0,0 +1,1226 @@ +/* ISO 8859-1 font file */ + +char font_8x8[256*8] = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E, +0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, +0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, +0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, +0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x7C, 0x38, 0x7C, +0x10, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, +0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00, +0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, +0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00, +0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF, +0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78, +0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, +0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0, +0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0, +0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99, +0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00, +0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00, +0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18, +0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, +0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00, +0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0xCC, 0x78, +0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00, +0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF, +0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00, +0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, +0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, +0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, +0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00, +0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00, +0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00, +0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, +0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, +0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, +0x30, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x30, 0x00, +0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00, +0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00, +0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, +0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, +0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, +0x00, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, +0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, +0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, +0x7C, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0x7C, 0x00, +0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00, +0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00, +0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00, +0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00, +0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00, +0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00, +0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, +0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00, +0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00, +0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, +0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, +0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00, +0x00, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00, +0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, +0x78, 0xCC, 0x0C, 0x18, 0x30, 0x00, 0x30, 0x00, +0x7C, 0xC6, 0xDE, 0xDE, 0xDE, 0xC0, 0x78, 0x00, +0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00, +0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, +0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00, +0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, +0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00, +0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00, +0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3E, 0x00, +0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00, +0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, +0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, +0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00, +0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, +0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00, +0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00, +0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, +0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, +0x78, 0xCC, 0xCC, 0xCC, 0xDC, 0x78, 0x1C, 0x00, +0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00, +0x78, 0xCC, 0xE0, 0x70, 0x1C, 0xCC, 0x78, 0x00, +0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, +0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00, +0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, +0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00, +0xC6, 0xC6, 0x6C, 0x38, 0x38, 0x6C, 0xC6, 0x00, +0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00, +0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00, +0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, +0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00, +0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, +0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, +0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, +0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00, +0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, +0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, +0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, +0x38, 0x6C, 0x60, 0xF0, 0x60, 0x60, 0xF0, 0x00, +0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, +0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00, +0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, +0x0C, 0x00, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, +0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00, +0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, +0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xC6, 0x00, +0x00, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, +0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, +0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0, +0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E, +0x00, 0x00, 0xDC, 0x76, 0x66, 0x60, 0xF0, 0x00, +0x00, 0x00, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x00, +0x10, 0x30, 0x7C, 0x30, 0x30, 0x34, 0x18, 0x00, +0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, +0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, +0x00, 0x00, 0xC6, 0xD6, 0xFE, 0xFE, 0x6C, 0x00, +0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00, +0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, +0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, +0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00, +0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, +0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00, +0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3C, 0x7E, 0xFF, 0x7E, 0x18, 0x00, +0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, +0x44, 0x44, 0x44, 0x44, 0x1F, 0x04, 0x04, 0x04, +0x7C, 0x40, 0x40, 0x40, 0x1F, 0x10, 0x10, 0x10, +0x38, 0x44, 0x44, 0x38, 0x1E, 0x11, 0x14, 0x13, +0x40, 0x40, 0x40, 0x7C, 0x1F, 0x10, 0x10, 0x10, +0x38, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, +0x44, 0x64, 0x4C, 0x44, 0x10, 0x10, 0x10, 0x1F, +0x44, 0x44, 0x28, 0x10, 0x1F, 0x04, 0x04, 0x04, +0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, +0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x00, 0x0C, 0x30, 0x60, 0x18, 0x0C, 0x7E, 0x00, +0x00, 0x30, 0x0C, 0x06, 0x18, 0x30, 0x7E, 0x00, +0x00, 0x00, 0x03, 0x3E, 0x36, 0x36, 0x6C, 0x00, +0x00, 0x00, 0x04, 0x7E, 0x10, 0x7E, 0x40, 0x00, +0x00, 0x1C, 0x30, 0x30, 0x30, 0x30, 0x7E, 0x00, +0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x30, 0x00, 0x30, 0x30, 0x78, 0x78, 0x30, 0x00, +0x00, 0x00, 0x10, 0x7C, 0xC0, 0xC0, 0x7C, 0x10, +0x00, 0x38, 0x60, 0x60, 0xF0, 0x60, 0xFC, 0x00, +0x00, 0xC3, 0x3C, 0x66, 0x66, 0x3C, 0xC3, 0x00, +0x00, 0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x30, 0x00, +0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, +0x7E, 0xC0, 0x7C, 0xC6, 0x7C, 0x06, 0xFC, 0x00, +0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7C, 0x82, 0xBA, 0xA2, 0xBA, 0x82, 0x7C, 0x00, +0x1C, 0x06, 0x1E, 0x22, 0x1F, 0x3F, 0x00, 0x00, +0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, +0x00, 0xFE, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7C, 0x82, 0xBA, 0xB2, 0xAA, 0x82, 0x7C, 0x00, +0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x38, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x10, 0x7C, 0x10, 0x00, 0x7C, 0x00, 0x00, +0x1C, 0x36, 0x06, 0x18, 0x3E, 0x00, 0x00, 0x00, +0x1E, 0x02, 0x0E, 0x02, 0x1E, 0x00, 0x00, 0x00, +0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0xC0, +0x7E, 0xCA, 0xCA, 0x7E, 0x0A, 0x0A, 0x0A, 0x00, +0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, +0x06, 0x0E, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, +0x0E, 0x11, 0x11, 0x11, 0x0E, 0x1F, 0x00, 0x00, +0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00, +0x60, 0xE0, 0x66, 0x6C, 0x33, 0x67, 0x0F, 0x03, +0x60, 0xE0, 0x66, 0x6C, 0x36, 0x6A, 0x04, 0x0E, +0xF0, 0x20, 0x96, 0x6C, 0x33, 0x67, 0x0F, 0x03, +0x30, 0x00, 0x30, 0x60, 0xC0, 0xCC, 0x78, 0x00, +0x18, 0x0C, 0x30, 0x78, 0xCC, 0xFC, 0xCC, 0x00, +0x60, 0xC0, 0x30, 0x78, 0xCC, 0xFC, 0xCC, 0x00, +0x78, 0x84, 0x30, 0x78, 0xCC, 0xFC, 0xCC, 0x00, +0x66, 0x98, 0x30, 0x78, 0xCC, 0xFC, 0xCC, 0x00, +0xCC, 0x00, 0x30, 0x78, 0xCC, 0xFC, 0xCC, 0x00, +0x30, 0x48, 0x30, 0x78, 0xCC, 0xFC, 0xCC, 0x00, +0x3E, 0x78, 0x98, 0x9C, 0xF8, 0x98, 0x9E, 0x00, +0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x1C, 0x30, +0x30, 0x18, 0xFE, 0x62, 0x78, 0x62, 0xFE, 0x00, +0x18, 0x30, 0xFE, 0x62, 0x78, 0x62, 0xFE, 0x00, +0x38, 0x44, 0xFE, 0x62, 0x78, 0x62, 0xFE, 0x00, +0x66, 0x00, 0xFE, 0x62, 0x78, 0x62, 0xFE, 0x00, +0x60, 0x30, 0x78, 0x30, 0x30, 0x30, 0x78, 0x00, +0x18, 0x30, 0x78, 0x30, 0x30, 0x30, 0x78, 0x00, +0x78, 0x84, 0x78, 0x30, 0x30, 0x30, 0x78, 0x00, +0xCC, 0x00, 0x78, 0x30, 0x30, 0x30, 0x78, 0x00, +0x78, 0x6C, 0x66, 0xF6, 0x66, 0x6C, 0x78, 0x00, +0x66, 0x98, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0x00, +0x30, 0x18, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, +0x18, 0x30, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, +0x38, 0x44, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, +0x66, 0x98, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, +0xC6, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, +0x00, 0xC6, 0x6C, 0x38, 0x38, 0x6C, 0xC6, 0x00, +0x06, 0x7C, 0xCE, 0x9A, 0xB2, 0xE6, 0x78, 0xC0, +0x60, 0x30, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00, +0x18, 0x30, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00, +0x78, 0x84, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00, +0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00, +0x18, 0x30, 0xCC, 0xCC, 0x78, 0x30, 0x78, 0x00, +0x60, 0x78, 0x6C, 0x78, 0x60, 0x60, 0x60, 0x00, +0x78, 0xCC, 0xC4, 0xDC, 0xC6, 0xC6, 0xDC, 0xC0, +0x30, 0x18, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, +0x18, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, +0x78, 0x84, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, +0x66, 0x98, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, +0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, +0x30, 0x48, 0x38, 0x0C, 0x7C, 0xCC, 0x76, 0x00, +0x00, 0x00, 0xEC, 0x32, 0x7E, 0xB0, 0x6E, 0x00, +0x00, 0x00, 0x3C, 0x66, 0xC0, 0x66, 0x1C, 0x30, +0x30, 0x18, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, +0x18, 0x30, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, +0x78, 0x84, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, +0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, +0x60, 0x30, 0x00, 0x70, 0x30, 0x30, 0x78, 0x00, +0x18, 0x30, 0x00, 0x70, 0x30, 0x30, 0x78, 0x00, +0x70, 0x88, 0x00, 0x70, 0x30, 0x30, 0x78, 0x00, +0xCC, 0x00, 0x00, 0x70, 0x30, 0x30, 0x78, 0x00, +0x6C, 0x38, 0x6C, 0x0C, 0x6C, 0xCC, 0x78, 0x00, +0x66, 0x98, 0xF8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, +0x60, 0x30, 0x00, 0x7C, 0xC6, 0xC6, 0x7C, 0x00, +0x18, 0x30, 0x00, 0x7C, 0xC6, 0xC6, 0x7C, 0x00, +0x38, 0x44, 0x00, 0x7C, 0xC6, 0xC6, 0x7C, 0x00, +0x66, 0x98, 0x00, 0x7C, 0xC6, 0xC6, 0x7C, 0x00, +0xC6, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x7C, 0x00, +0x00, 0x00, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x00, +0x00, 0x00, 0x06, 0x7C, 0xDE, 0xF6, 0x7C, 0xC0, +0x60, 0x30, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, +0x18, 0x30, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, +0x30, 0x48, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, +0xCC, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, +0x18, 0x30, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, +0xE0, 0x78, 0x6C, 0x66, 0x6C, 0x78, 0xE0, 0x00, +0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8 +}; + +char font_8x14[256*14] = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7E, 0x81, 0xA5, 0x81, 0x81, 0xBD, 0x99, 0x81, +0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xFF, +0xDB, 0xFF, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x7F, 0x7F, +0x7F, 0x7F, 0x3E, 0x1C, 0x08, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x08, 0x1C, 0x3E, 0x7F, 0x3E, +0x1C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x3C, 0x3C, 0xE7, 0xE7, 0xE7, 0x18, 0x18, +0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, +0x7E, 0xFF, 0xFF, 0x7E, 0x18, 0x18, 0x3C, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, +0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, +0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, +0x00, 0x00, 0x3C, 0x24, 0x42, 0x42, 0x24, 0x3C, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, +0xC3, 0xDB, 0xBD, 0xBD, 0xDB, 0xC3, 0xFF, 0xFF, +0xFF, 0xFF, 0x00, 0x00, 0x1F, 0x07, 0x0D, 0x19, +0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, +0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, +0x0C, 0x0A, 0x09, 0x09, 0x09, 0x0A, 0x08, 0x38, +0x78, 0x78, 0x30, 0x00, 0x00, 0x00, 0x1F, 0x11, +0x1F, 0x11, 0x11, 0x11, 0x13, 0x37, 0x77, 0x72, +0x20, 0x00, 0x00, 0x00, 0x18, 0x18, 0xDB, 0x3C, +0xE7, 0x3C, 0xDB, 0x18, 0x18, 0x00, 0x00, 0x00, +0x00, 0x00, 0x40, 0x60, 0x70, 0x7C, 0x7F, 0x7C, +0x70, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x03, 0x07, 0x1F, 0x7F, 0x1F, 0x07, 0x03, +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, +0x7E, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, +0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, +0x33, 0x33, 0x00, 0x33, 0x33, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7F, 0xDB, 0xDB, 0xDB, 0x7B, 0x1B, +0x1B, 0x1B, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x3E, +0x63, 0x30, 0x1C, 0x36, 0x63, 0x63, 0x36, 0x1C, +0x06, 0x63, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x7F, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, +0x18, 0x18, 0x7E, 0x3C, 0x18, 0x7E, 0x00, 0x00, +0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, +0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x0C, 0x06, 0x7F, 0x06, 0x0C, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, +0x7F, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, +0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x24, 0x42, 0xFF, 0x42, 0x24, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, +0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, +0x18, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, +0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x7F, 0x36, +0x36, 0x36, 0x7F, 0x36, 0x36, 0x00, 0x00, 0x00, +0x08, 0x08, 0x3E, 0x63, 0x60, 0x60, 0x3E, 0x03, +0x03, 0x63, 0x3E, 0x08, 0x08, 0x00, 0x00, 0x00, +0x00, 0x61, 0x63, 0x06, 0x0C, 0x18, 0x30, 0x63, +0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x36, +0x36, 0x1C, 0x3B, 0x6E, 0x66, 0x66, 0x3B, 0x00, +0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, +0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, +0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x18, +0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x66, 0x3C, 0x7E, 0x3C, 0x66, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, +0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, +0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0C, +0x18, 0x30, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3E, 0x63, 0x67, 0x6F, 0x7B, 0x73, +0x63, 0x63, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, +0x0C, 0x1C, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x63, +0x03, 0x06, 0x0C, 0x18, 0x30, 0x63, 0x7F, 0x00, +0x00, 0x00, 0x00, 0x00, 0x3E, 0x63, 0x03, 0x03, +0x1E, 0x03, 0x03, 0x63, 0x3E, 0x00, 0x00, 0x00, +0x00, 0x00, 0x06, 0x0E, 0x1E, 0x36, 0x66, 0x7F, +0x06, 0x06, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7E, 0x60, 0x60, 0x60, 0x7E, 0x03, 0x03, 0x63, +0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x30, +0x60, 0x60, 0x7E, 0x63, 0x63, 0x63, 0x3E, 0x00, +0x00, 0x00, 0x00, 0x00, 0x7F, 0x63, 0x03, 0x06, +0x0C, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3E, 0x63, 0x63, 0x63, 0x3E, 0x63, +0x63, 0x63, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, +0x3E, 0x63, 0x63, 0x63, 0x3F, 0x03, 0x03, 0x06, +0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, +0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, +0x00, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x30, +0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x7E, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, +0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, +0x00, 0x00, 0x00, 0x00, 0x3E, 0x63, 0x63, 0x06, +0x0C, 0x0C, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3E, 0x63, 0x63, 0x6F, 0x6F, 0x6F, +0x6E, 0x60, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, +0x08, 0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63, 0x63, +0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x33, +0x33, 0x33, 0x3E, 0x33, 0x33, 0x33, 0x7E, 0x00, +0x00, 0x00, 0x00, 0x00, 0x1E, 0x33, 0x60, 0x60, +0x60, 0x60, 0x60, 0x33, 0x1E, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7C, 0x36, 0x33, 0x33, 0x33, 0x33, +0x33, 0x36, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7F, 0x33, 0x30, 0x34, 0x3C, 0x34, 0x30, 0x33, +0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x33, +0x30, 0x34, 0x3C, 0x34, 0x30, 0x30, 0x78, 0x00, +0x00, 0x00, 0x00, 0x00, 0x1E, 0x33, 0x60, 0x60, +0x60, 0x6F, 0x63, 0x33, 0x1D, 0x00, 0x00, 0x00, +0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x7F, 0x63, +0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, +0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x06, +0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, 0x00, +0x00, 0x00, 0x00, 0x00, 0x73, 0x33, 0x36, 0x36, +0x3C, 0x36, 0x36, 0x33, 0x73, 0x00, 0x00, 0x00, +0x00, 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, +0x30, 0x33, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, +0x63, 0x77, 0x7F, 0x6B, 0x63, 0x63, 0x63, 0x63, +0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x73, +0x7B, 0x7F, 0x6F, 0x67, 0x63, 0x63, 0x63, 0x00, +0x00, 0x00, 0x00, 0x00, 0x1C, 0x36, 0x63, 0x63, +0x63, 0x63, 0x63, 0x36, 0x1C, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7E, 0x33, 0x33, 0x33, 0x3E, 0x30, +0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, +0x1C, 0x36, 0x63, 0x63, 0x63, 0x63, 0x6B, 0x3E, +0x1C, 0x06, 0x03, 0x00, 0x00, 0x00, 0x7E, 0x33, +0x33, 0x33, 0x3E, 0x36, 0x33, 0x33, 0x73, 0x00, +0x00, 0x00, 0x00, 0x00, 0x3E, 0x63, 0x63, 0x30, +0x1C, 0x06, 0x63, 0x63, 0x3E, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, +0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, +0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, +0x63, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x08, 0x00, +0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, +0x63, 0x6B, 0x6B, 0x7F, 0x36, 0x00, 0x00, 0x00, +0x00, 0x00, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x36, +0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, +0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, +0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x63, +0x06, 0x0C, 0x18, 0x30, 0x60, 0x63, 0x7F, 0x00, +0x00, 0x00, 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, +0x30, 0x30, 0x30, 0x30, 0x3C, 0x00, 0x00, 0x00, +0x00, 0x00, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x06, +0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +0x3C, 0x00, 0x00, 0x00, 0x08, 0x1C, 0x36, 0x63, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, +0x18, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x66, +0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x30, +0x30, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, +0x63, 0x60, 0x60, 0x63, 0x3E, 0x00, 0x00, 0x00, +0x00, 0x00, 0x0E, 0x06, 0x06, 0x3E, 0x66, 0x66, +0x66, 0x66, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x3E, 0x63, 0x7F, 0x60, 0x63, +0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x33, +0x30, 0x7C, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3B, +0x66, 0x66, 0x66, 0x3E, 0x06, 0x66, 0x3C, 0x00, +0x00, 0x00, 0x70, 0x30, 0x30, 0x36, 0x3B, 0x33, +0x33, 0x33, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, +0x0C, 0x0C, 0x00, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C, +0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, +0x00, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xCC, +0x78, 0x00, 0x00, 0x00, 0x70, 0x30, 0x30, 0x33, +0x36, 0x3C, 0x36, 0x33, 0x73, 0x00, 0x00, 0x00, +0x00, 0x00, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x66, 0x7F, 0x6B, 0x6B, 0x6B, +0x6B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x6E, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, +0x63, 0x63, 0x63, 0x63, 0x3E, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x33, 0x33, +0x33, 0x3E, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x3B, 0x66, 0x66, 0x66, 0x3E, +0x06, 0x06, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x6E, 0x33, 0x30, 0x30, 0x30, 0x78, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, +0x63, 0x38, 0x0E, 0x63, 0x3E, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x08, 0x18, 0x7E, 0x18, 0x18, +0x18, 0x1B, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, +0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x08, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, +0x63, 0x6B, 0x6B, 0x7F, 0x36, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x36, 0x1C, +0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x63, 0x66, 0x66, 0x66, 0x3E, +0x06, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7F, 0x66, 0x0C, 0x18, 0x33, 0x7F, 0x00, +0x00, 0x00, 0x00, 0x00, 0x0E, 0x18, 0x18, 0x18, +0x70, 0x18, 0x18, 0x18, 0x0E, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, +0x70, 0x18, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x18, +0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3B, 0x6E, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1C, +0x36, 0x63, 0x63, 0x7F, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x3C, +0x18, 0x00, 0x00, 0x00, 0x55, 0xAA, 0x55, 0xAA, +0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, +0x55, 0xAA, 0x00, 0x44, 0x44, 0x7C, 0x44, 0x44, +0x00, 0x1F, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, +0x00, 0x7C, 0x40, 0x78, 0x40, 0x40, 0x00, 0x1F, +0x10, 0x1E, 0x10, 0x10, 0x00, 0x00, 0x00, 0x38, +0x44, 0x40, 0x44, 0x38, 0x00, 0x1E, 0x11, 0x1E, +0x14, 0x13, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, +0x40, 0x7C, 0x00, 0x1F, 0x10, 0x1E, 0x10, 0x10, +0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, +0x18, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x44, +0x64, 0x54, 0x4C, 0x44, 0x00, 0x10, 0x10, 0x10, +0x10, 0x1F, 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, +0x28, 0x10, 0x00, 0x1F, 0x04, 0x04, 0x04, 0x04, +0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x0C, 0x18, +0x30, 0x60, 0x30, 0x18, 0x0C, 0x00, 0x7E, 0x00, +0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x0C, 0x06, +0x0C, 0x18, 0x30, 0x00, 0x7E, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x03, 0x3E, 0x76, 0x36, +0x36, 0x36, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x02, 0x04, 0x7E, 0x08, 0x10, 0x7E, 0x20, +0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x36, +0x30, 0x30, 0x7C, 0x30, 0x30, 0x73, 0x7E, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, +0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x3C, +0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, +0x08, 0x3E, 0x63, 0x60, 0x60, 0x63, 0x3E, 0x08, +0x08, 0x00, 0x00, 0x00, 0x1C, 0x36, 0x30, 0x30, +0x7C, 0x30, 0x30, 0x73, 0x7E, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x42, 0x3C, 0x66, 0x66, 0x66, +0x3C, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x7E, +0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, +0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, +0x00, 0x00, 0x00, 0x3E, 0x63, 0x30, 0x1C, 0x36, +0x63, 0x63, 0x36, 0x1C, 0x06, 0x63, 0x3E, 0x00, +0x00, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x3E, 0x41, 0x5D, 0x51, 0x51, 0x5D, 0x41, +0x3E, 0x00, 0x00, 0x00, 0x00, 0x38, 0x04, 0x3C, +0x44, 0x3C, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x36, +0x6C, 0x36, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x03, +0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, +0x41, 0x5D, 0x55, 0x59, 0x55, 0x41, 0x3E, 0x00, +0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, +0x7E, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0x18, +0x30, 0x64, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x7C, 0x0C, 0x38, 0x0C, 0x6C, +0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x06, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, +0x3B, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x7F, 0xDB, +0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, +0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x0C, 0x0C, 0x06, 0x1C, 0x00, 0x30, +0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, +0x44, 0x38, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x36, +0x1B, 0x36, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x60, 0xE0, 0x63, 0x66, 0x6C, 0x18, 0x33, +0x67, 0xCF, 0x1F, 0x03, 0x03, 0x00, 0x00, 0x60, +0xE0, 0x63, 0x66, 0x6C, 0x18, 0x30, 0x6E, 0xC3, +0x06, 0x0C, 0x1F, 0x00, 0x00, 0xF0, 0x30, 0x63, +0xF6, 0x6C, 0x18, 0x33, 0x67, 0xCF, 0x1F, 0x03, +0x03, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, +0x18, 0x30, 0x63, 0x63, 0x3E, 0x00, 0x00, 0x00, +0x60, 0x30, 0x18, 0x00, 0x1C, 0x36, 0x63, 0x63, +0x7F, 0x63, 0x63, 0x00, 0x00, 0x00, 0x03, 0x06, +0x0C, 0x00, 0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63, +0x63, 0x00, 0x00, 0x00, 0x08, 0x1C, 0x36, 0x00, +0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x00, +0x00, 0x00, 0x3B, 0x6E, 0x00, 0x08, 0x1C, 0x36, +0x63, 0x63, 0x7F, 0x63, 0x63, 0x00, 0x00, 0x00, +0x00, 0x63, 0x63, 0x08, 0x1C, 0x36, 0x63, 0x63, +0x7F, 0x63, 0x63, 0x00, 0x00, 0x00, 0x1C, 0x36, +0x1C, 0x00, 0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63, +0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x36, +0x66, 0x66, 0x67, 0x7E, 0x66, 0x66, 0x67, 0x00, +0x00, 0x00, 0x00, 0x00, 0x1E, 0x33, 0x60, 0x60, +0x60, 0x60, 0x60, 0x33, 0x1E, 0x0C, 0x06, 0x1C, +0x60, 0x30, 0x18, 0x00, 0x7F, 0x33, 0x30, 0x3E, +0x30, 0x33, 0x7F, 0x00, 0x00, 0x00, 0x06, 0x0C, +0x18, 0x00, 0x7F, 0x33, 0x30, 0x3E, 0x30, 0x33, +0x7F, 0x00, 0x00, 0x00, 0x08, 0x1C, 0x36, 0x00, +0x7F, 0x33, 0x30, 0x3E, 0x30, 0x33, 0x7F, 0x00, +0x00, 0x00, 0x00, 0x63, 0x63, 0x00, 0x7F, 0x33, +0x30, 0x3E, 0x30, 0x33, 0x7F, 0x00, 0x00, 0x00, +0x60, 0x30, 0x18, 0x00, 0x3C, 0x18, 0x18, 0x18, +0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x06, 0x0C, +0x18, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, +0x3C, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x66, 0x00, +0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, +0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x3C, 0x18, +0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3C, 0x36, 0x33, 0x33, 0x7B, 0x33, +0x33, 0x36, 0x3C, 0x00, 0x00, 0x00, 0x3B, 0x6E, +0x00, 0x63, 0x73, 0x7B, 0x7F, 0x6F, 0x67, 0x63, +0x63, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, +0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00, +0x00, 0x00, 0x03, 0x06, 0x0C, 0x00, 0x1C, 0x36, +0x63, 0x63, 0x63, 0x36, 0x1C, 0x00, 0x00, 0x00, +0x08, 0x1C, 0x36, 0x00, 0x1C, 0x36, 0x63, 0x63, +0x63, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x3B, +0x6E, 0x00, 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, +0x1C, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x00, +0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x36, 0x1C, +0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00, +0x00, 0x03, 0x1E, 0x36, 0x67, 0x6F, 0x6B, 0x7B, +0x73, 0x36, 0x3C, 0x60, 0x00, 0x00, 0x60, 0x30, +0x18, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, +0x3E, 0x00, 0x00, 0x00, 0x03, 0x06, 0x0C, 0x00, +0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x00, +0x00, 0x00, 0x08, 0x1C, 0x36, 0x00, 0x63, 0x63, +0x63, 0x63, 0x63, 0x63, 0x3E, 0x00, 0x00, 0x00, +0x00, 0x63, 0x63, 0x00, 0x63, 0x63, 0x63, 0x63, +0x63, 0x63, 0x3E, 0x00, 0x00, 0x00, 0x06, 0x0C, +0x18, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, +0x3C, 0x00, 0x00, 0x00, 0x00, 0x78, 0x30, 0x3E, +0x33, 0x33, 0x3E, 0x30, 0x30, 0x30, 0x78, 0x00, +0x00, 0x00, 0x00, 0x00, 0x1C, 0x36, 0x63, 0x66, +0x6C, 0x67, 0x63, 0x6B, 0x6E, 0x60, 0x60, 0x00, +0x00, 0x60, 0x30, 0x18, 0x00, 0x3C, 0x06, 0x3E, +0x66, 0x66, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x06, +0x0C, 0x18, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x66, +0x3B, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1C, 0x36, +0x00, 0x3C, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00, +0x00, 0x00, 0x00, 0x00, 0x3B, 0x6E, 0x00, 0x3C, +0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00, 0x00, 0x00, +0x00, 0x00, 0x66, 0x66, 0x00, 0x3C, 0x06, 0x3E, +0x66, 0x66, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x1C, +0x36, 0x1C, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x66, +0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x76, 0x0B, 0x3B, 0x6E, 0x68, 0x37, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, +0x63, 0x60, 0x60, 0x63, 0x3E, 0x0C, 0x06, 0x1C, +0x00, 0x30, 0x18, 0x0C, 0x00, 0x3E, 0x63, 0x7F, +0x60, 0x63, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x03, +0x06, 0x0C, 0x00, 0x3E, 0x63, 0x7F, 0x60, 0x63, +0x3E, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1C, 0x36, +0x00, 0x3E, 0x63, 0x7F, 0x60, 0x63, 0x3E, 0x00, +0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x00, 0x3E, +0x63, 0x7F, 0x60, 0x63, 0x3E, 0x00, 0x00, 0x00, +0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, +0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x06, +0x0C, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, +0x3C, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x66, +0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, +0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x38, +0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, +0x00, 0x00, 0x36, 0x1C, 0x36, 0x06, 0x3E, 0x66, +0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, +0x3B, 0x6E, 0x00, 0x6E, 0x33, 0x33, 0x33, 0x33, +0x33, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, +0x00, 0x3E, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x00, +0x00, 0x00, 0x00, 0x06, 0x0C, 0x18, 0x00, 0x3E, +0x63, 0x63, 0x63, 0x63, 0x3E, 0x00, 0x00, 0x00, +0x00, 0x08, 0x1C, 0x36, 0x00, 0x3E, 0x63, 0x63, +0x63, 0x63, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, +0x3B, 0x6E, 0x00, 0x3E, 0x63, 0x63, 0x63, 0x63, +0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, +0x00, 0x3E, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, +0x7E, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x03, 0x3E, 0x67, 0x6F, +0x7B, 0x73, 0x3E, 0x60, 0x00, 0x00, 0x00, 0x60, +0x30, 0x18, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, +0x3B, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0C, 0x18, +0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3B, 0x00, +0x00, 0x00, 0x00, 0x18, 0x3C, 0x66, 0x00, 0x66, +0x66, 0x66, 0x66, 0x66, 0x3B, 0x00, 0x00, 0x00, +0x00, 0x00, 0x66, 0x66, 0x00, 0x66, 0x66, 0x66, +0x66, 0x66, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x06, +0x0C, 0x18, 0x00, 0x63, 0x66, 0x66, 0x66, 0x3E, +0x06, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x78, +0x30, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x3E, 0x30, +0x78, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x66, +0x66, 0x66, 0x66, 0x3E, 0x06, 0x66, 0x3C, 0x00 +}; + +char font_8x16[256*16] = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0x81, 0xBD, +0x99, 0x81, 0x81, 0x7E, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7E, 0xFF, 0xDB, 0xFF, 0xFF, 0xC3, +0xE7, 0xFF, 0xFF, 0x7E, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x6C, 0xFE, 0xFE, 0xFE, +0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7C, 0xFE, +0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0xE7, 0xE7, +0xE7, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, +0x7E, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, +0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC3, +0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x42, +0x42, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x99, 0xBD, +0xBD, 0x99, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0x00, 0x00, 0x1E, 0x0E, 0x1A, 0x32, 0x78, 0xCC, +0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, +0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3F, 0x33, 0x3F, 0x30, 0x30, 0x30, +0x30, 0x70, 0xF0, 0xE0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x63, +0x63, 0x67, 0xE7, 0xE6, 0xC0, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x18, 0x18, 0xDB, 0x3C, 0xE7, +0x3C, 0xDB, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFE, 0xF8, +0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, +0x00, 0x02, 0x06, 0x0E, 0x1E, 0x3E, 0xFE, 0x3E, +0x1E, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, +0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, +0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7F, 0xDB, 0xDB, 0xDB, 0x7B, 0x1B, +0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7C, 0xC6, 0x60, 0x38, 0x6C, 0xC6, 0xC6, +0x6C, 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFE, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, +0x7E, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0C, 0xFE, +0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, +0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, +0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xFF, +0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7C, +0x7C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x7C, 0x7C, +0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x18, +0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, +0x6C, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, +0x18, 0x18, 0x7C, 0xC6, 0xC2, 0xC0, 0x7C, 0x06, +0x06, 0x86, 0xC6, 0x7C, 0x18, 0x18, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xC2, 0xC6, 0x0C, 0x18, +0x30, 0x60, 0xC6, 0x86, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x76, 0xDC, +0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, +0x30, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x0C, +0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3C, 0xFF, +0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, +0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0C, 0x18, +0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xDB, 0xDB, +0xC3, 0xC3, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7C, 0xC6, 0x06, 0x0C, 0x18, 0x30, +0x60, 0xC0, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, +0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, +0x0C, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xFC, 0x06, +0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x60, 0xC0, 0xC0, 0xFC, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xFE, 0xC6, 0x06, 0x06, 0x0C, 0x18, +0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, +0x06, 0x06, 0x0C, 0x78, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, +0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, +0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, +0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, +0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, +0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x0C, 0x18, 0x18, +0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xDE, 0xDE, +0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, +0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, +0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0, +0xC0, 0xC2, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x66, +0x66, 0x66, 0x6C, 0xF8, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, +0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, +0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xDE, +0xC6, 0xC6, 0x66, 0x3A, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, +0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xE6, 0x66, 0x66, 0x6C, 0x78, 0x78, +0x6C, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x60, +0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xC3, 0xE7, 0xFF, 0xFF, 0xDB, 0xC3, +0xC3, 0xC3, 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, +0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x60, +0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, +0xC6, 0xD6, 0xDE, 0x7C, 0x0C, 0x0E, 0x00, 0x00, +0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x6C, +0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x38, 0x0C, +0x06, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xFF, 0xDB, 0x99, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, +0xC3, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xDB, +0xDB, 0xFF, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xC3, 0xC3, 0x66, 0x3C, 0x18, 0x18, +0x3C, 0x66, 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, 0x18, +0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xFF, 0xC3, 0x86, 0x0C, 0x18, 0x30, +0x60, 0xC1, 0xC3, 0xFF, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, +0x30, 0x30, 0x30, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38, +0x1C, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +0x0C, 0x0C, 0x0C, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, +0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, +0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xE0, 0x60, 0x60, 0x78, 0x6C, 0x66, +0x66, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, +0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x1C, 0x0C, 0x0C, 0x3C, 0x6C, 0xCC, +0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xFE, +0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, +0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, +0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xCC, 0x78, 0x00, +0x00, 0x00, 0xE0, 0x60, 0x60, 0x6C, 0x76, 0x66, +0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x06, 0x06, 0x00, 0x0E, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, 0x00, +0x00, 0x00, 0xE0, 0x60, 0x60, 0x66, 0x6C, 0x78, +0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xFF, 0xDB, +0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, +0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, +0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, +0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0x0C, 0x1E, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x76, 0x66, +0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x60, +0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x10, 0x30, 0x30, 0xFC, 0x30, 0x30, +0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, +0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xC3, 0xC3, +0xC3, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xC3, 0xC3, +0xDB, 0xDB, 0xFF, 0x66, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x66, 0x3C, +0x18, 0x3C, 0x66, 0xC3, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0xF8, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xCC, 0x18, +0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x0E, 0x18, 0x18, 0x18, 0x70, 0x18, +0x18, 0x18, 0x18, 0x0E, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0E, 0x18, +0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, +0xC6, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0xFF, +0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, +0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, +0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, +0x00, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88, 0x00, +0x3E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, +0x00, 0xF8, 0x80, 0xF0, 0x80, 0x80, 0x80, 0x00, +0x3E, 0x20, 0x3C, 0x20, 0x20, 0x20, 0x00, 0x00, +0x00, 0x70, 0x88, 0x80, 0x80, 0x88, 0x70, 0x00, +0x3C, 0x22, 0x3C, 0x28, 0x24, 0x22, 0x00, 0x00, +0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF8, 0x00, +0x3E, 0x20, 0x3C, 0x20, 0x20, 0x20, 0x00, 0x00, +0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, +0x18, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, +0x00, 0x88, 0xC8, 0xA8, 0xA8, 0x98, 0x88, 0x00, +0x20, 0x20, 0x20, 0x20, 0x20, 0x3E, 0x00, 0x00, +0x00, 0x88, 0x88, 0x88, 0x88, 0x50, 0x20, 0x00, +0x3E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x60, 0x30, +0x18, 0x0C, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x30, 0x18, 0x0C, 0x06, 0x0C, +0x18, 0x30, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x7E, 0xEC, 0x6C, 0x6C, +0x6C, 0x6C, 0x6C, 0xCC, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x06, 0x0C, 0x7E, 0x18, 0x18, +0x7E, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, +0x60, 0x60, 0xE6, 0xFC, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, +0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, +0x3C, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x18, 0x18, 0x7E, 0xC3, 0xC0, 0xC0, 0xC0, +0xC3, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, +0x60, 0x60, 0xE6, 0xFC, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x82, 0xC6, 0x7C, 0xC6, 0xC6, +0xC6, 0xC6, 0x7C, 0xC6, 0x82, 0x00, 0x00, 0x00, +0x00, 0x00, 0xC3, 0x66, 0x3C, 0x18, 0xFF, 0x18, +0xFF, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, +0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7C, 0xC6, 0x60, 0x38, 0x6C, 0xC6, 0xC6, +0x6C, 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00, +0x00, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7C, 0xC6, 0x82, 0xBA, 0xA2, 0xA2, +0xBA, 0x82, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x70, 0x18, 0x78, 0xC8, 0x78, 0x00, 0xF8, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6C, 0xD8, +0x6C, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06, +0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7C, 0xC6, 0x82, 0xBA, 0xAA, 0xB2, +0xAA, 0x82, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, +0x18, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, +0x00, 0x70, 0xD8, 0x30, 0x60, 0xC8, 0xF8, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xF8, 0x18, 0x30, 0x18, 0xD8, 0x70, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, +0x66, 0x7E, 0x63, 0x60, 0xC0, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7F, 0xDB, 0xDB, 0xDB, 0x7B, 0x1B, +0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, +0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x0C, 0x06, 0x3C, 0x00, 0x00, +0x00, 0x60, 0xE0, 0x60, 0x60, 0x60, 0xF0, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x70, 0xD8, 0x88, 0xD8, 0x70, 0x00, 0xF8, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x6C, 0x36, +0x6C, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xC0, 0xC0, 0xC2, 0xC6, 0xCC, 0x18, 0x30, +0x66, 0xCE, 0x96, 0x3E, 0x06, 0x06, 0x00, 0x00, +0x00, 0xC0, 0xC0, 0xC2, 0xC6, 0xCC, 0x18, 0x30, +0x60, 0xCE, 0x9B, 0x06, 0x0C, 0x1F, 0x00, 0x00, +0x00, 0xF0, 0x30, 0x72, 0x36, 0xEC, 0x18, 0x30, +0x66, 0xCE, 0x96, 0x3E, 0x06, 0x06, 0x00, 0x00, +0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, +0xC0, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x60, 0x30, 0x18, 0x00, 0x38, 0x6C, 0xC6, 0xC6, +0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, +0x0C, 0x18, 0x30, 0x00, 0x38, 0x6C, 0xC6, 0xC6, +0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, +0x10, 0x38, 0x6C, 0x00, 0x38, 0x6C, 0xC6, 0xC6, +0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x76, 0xDC, 0x00, 0x38, 0x6C, 0xC6, 0xC6, +0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, +0x00, 0xC6, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, +0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, +0x38, 0x6C, 0x38, 0x00, 0x38, 0x6C, 0xC6, 0xC6, +0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3E, 0x6C, 0xCC, 0xCC, 0xFE, 0xCC, +0xCC, 0xCC, 0xCC, 0xCE, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0, +0xC2, 0x66, 0x3C, 0x0C, 0x06, 0x7C, 0x00, 0x00, +0x30, 0x18, 0x0C, 0x00, 0xFE, 0x66, 0x60, 0x7C, +0x60, 0x60, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, +0x18, 0x30, 0x60, 0x00, 0xFE, 0x66, 0x60, 0x7C, +0x60, 0x60, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, +0x10, 0x38, 0x6C, 0x00, 0xFE, 0x66, 0x60, 0x7C, +0x60, 0x60, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, +0x00, 0xC6, 0x00, 0xFE, 0x66, 0x60, 0x60, 0x7C, +0x60, 0x60, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, +0x30, 0x18, 0x0C, 0x00, 0x3C, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x0C, 0x18, 0x30, 0x00, 0x3C, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x18, 0x3C, 0x66, 0x00, 0x3C, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x66, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x78, 0x6C, 0x66, 0x66, 0x66, 0xF6, +0x66, 0x66, 0x6C, 0x78, 0x00, 0x00, 0x00, 0x00, +0x76, 0xDC, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, +0xCE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, +0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x0C, 0x18, 0x30, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x76, 0xDC, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0xC6, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x10, +0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x06, 0x7C, 0xCE, 0xCE, 0xDE, 0xD6, 0xD6, +0xF6, 0xE6, 0xE6, 0x7C, 0xC0, 0x80, 0x00, 0x00, +0x60, 0x30, 0x18, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x0C, 0x18, 0x30, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x10, 0x38, 0x6C, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x0C, 0x18, 0x30, 0x00, 0xC3, 0xC3, 0x66, 0x3C, +0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, +0xF0, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x7C, 0x60, +0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x6C, 0xC6, 0xCE, 0xDC, 0xD8, +0xCC, 0xC6, 0xD6, 0xDC, 0xC0, 0x80, 0x00, 0x00, +0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0C, 0x7C, +0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0C, 0x7C, +0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x10, 0x38, 0x6C, 0x00, 0x78, 0x0C, 0x7C, +0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x76, 0xDC, 0x00, 0x78, 0x0C, 0x7C, +0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xCC, 0x00, 0x00, 0x78, 0x0C, 0x7C, +0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x38, 0x6C, 0x38, 0x00, 0x78, 0x0C, 0x7C, +0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x3B, 0x1B, +0x7E, 0xD8, 0xDC, 0x77, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x60, 0x60, +0x66, 0x3C, 0x0C, 0x06, 0x3C, 0x00, 0x00, 0x00, +0x00, 0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xFE, +0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0C, 0x18, 0x30, 0x00, 0x7C, 0xC6, 0xFE, +0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xFE, +0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xC6, 0x00, 0x00, 0x7C, 0xC6, 0xFE, +0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x06, 0x0C, 0x18, 0x00, 0x38, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x18, 0x3C, 0x66, 0x00, 0x38, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x6C, 0x38, 0x38, 0x6C, 0x0C, 0x3C, 0x6C, +0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x76, 0xDC, 0x00, 0xDC, 0x66, 0x66, +0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, +0x00, 0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x18, 0x30, 0x60, 0x00, 0x7C, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x76, 0xDC, 0x00, 0x7C, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xC6, 0x00, 0x00, 0x7C, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7E, +0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x06, 0x7C, 0xCE, 0xDE, +0xD6, 0xF6, 0xE6, 0x7C, 0xC0, 0x80, 0x00, 0x00, +0x00, 0x60, 0x30, 0x18, 0x00, 0xCC, 0xCC, 0xCC, +0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x18, 0x30, 0x60, 0x00, 0xCC, 0xCC, 0xCC, +0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x30, 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, +0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xCC, 0x00, 0x00, 0xCC, 0xCC, 0xCC, +0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x18, 0x30, 0x60, 0x00, 0xC6, 0xC6, 0xC6, +0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0xF8, 0x00, +0x00, 0x00, 0x00, 0xF0, 0x60, 0x7C, 0x66, 0x66, +0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, +0x00, 0x00, 0x66, 0x66, 0x00, 0xEE, 0x66, 0x66, +0x66, 0x66, 0x66, 0x3E, 0x06, 0x0C, 0x38, 0x00 +}; diff --git a/sys/i386/isa/kbdtables.h b/sys/i386/isa/kbdtables.h new file mode 100644 index 000000000000..013cf59e9b7f --- /dev/null +++ b/sys/i386/isa/kbdtables.h @@ -0,0 +1,265 @@ +/* + * Copyright (C) 1992, 1993 Søren Schmidt + * + * This program is free software; you may redistribute it and/or + * modify it, provided that it retain the above copyright notice + * and the following disclaimer. + * + * 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. + * + * Søren Schmidt Email: sos@kmd-ac.dk + * Tritonvej 36 UUCP: ...uunet!dkuug!kmd-ac!sos + * DK9210 Aalborg SO Phone: +45 9814 8076 + */ + +#if defined(DKKEYMAP) + +keymap_t key_map = { 107, /* DK iso8859 keymap */ +/* alt + * scan cntrl alt alt cntrl + * code base shift cntrl shift alt shift cntrl shift spcl flgs + * --------------------------------------------------------------------------- + */ +/* sc=00 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=01 */ 0x1B, 0x1B, NOP, NOP, 0x1B, 0x1B, NOP, NOP, 0x33, 0x00, +/* sc=02 */ '1', '!', NOP, NOP, '1', '!', NOP, NOP, 0x33, 0x00, +/* sc=03 */ '2', '"', 0x00, 0x00, '@', '"', 0x00, 0x00, 0x00, 0x00, +/* sc=04 */ '3', '#', NOP, NOP, 0x9E, '#', NOP, NOP, 0x33, 0x00, +/* sc=05 */ '4', 0xA4, NOP, NOP, '$', 0xA4, NOP, NOP, 0x33, 0x00, +/* sc=06 */ '5', '%', NOP, NOP, '5', '%', NOP, NOP, 0x33, 0x00, +/* sc=07 */ '6', '&', NOP, NOP, '6', '&', NOP, NOP, 0x33, 0x00, +/* sc=08 */ '7', '/', NOP, NOP, '{', '/', NOP, NOP, 0x33, 0x00, +/* sc=09 */ '8', '(', 0x1B, 0x1B, '[', '(', 0x1B, 0x1B, 0x00, 0x00, +/* sc=0a */ '9', ')', 0x1D, 0x1D, ']', ')', 0x1D, 0x1D, 0x00, 0x00, +/* sc=0b */ '0', '=', NOP, NOP, '}', '=', NOP, NOP, 0x33, 0x00, +/* sc=0c */ '+', '?', NOP, NOP, '+', '?', NOP, NOP, 0x33, 0x00, +/* sc=0d */ '\'', '`', NOP, NOP, '|', '`', NOP, NOP, 0x33, 0x00, +/* sc=0e */ 0x08, 0x08, 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00, +/* sc=0f */ 0x09, 0x08, NOP, NOP, 0x09, 0x08, NOP, NOP, 0x33, 0x00, +/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01, +/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01, +/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01, +/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01, +/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01, +/* sc=15 */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01, +/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01, +/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01, +/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01, +/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01, +/* sc=1a */ 0xE5, 0xC5, NOP, NOP, 0x86, 0x8F, NOP, NOP, 0x33, 0x01, +/* sc=1b */ '"', '^', 0x1E, 0x1E, '~', '^', 0x1E, 0x1E, 0x00, 0x00, +/* sc=1c */ 0x0D, 0x0D, 0x0A, 0x0A, 0x0D, 0x0D, 0x0A, 0x0A, 0x00, 0x00, +/* sc=1d */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00, +/* sc=1e */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01, +/* sc=1f */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01, +/* sc=20 */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01, +/* sc=21 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01, +/* sc=22 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01, +/* sc=23 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01, +/* sc=24 */ 'j', 'J', 0x0A, 0x0A, 'j', 'J', 0x0A, 0x0A, 0x00, 0x01, +/* sc=25 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01, +/* sc=26 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01, +/* sc=27 */ 0xE6, 0xC6, NOP, NOP, 0x91, 0x92, NOP, NOP, 0x33, 0x01, +/* sc=28 */ 0xF8, 0xD8, NOP, NOP, 0x9B, 0x9D, NOP, NOP, 0x33, 0x01, +/* sc=29 */ 0xBD, 0xA7, NOP, NOP, 0xBD, 0xA7, NOP, NOP, 0x33, 0x00, +/* sc=2a */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00, +/* sc=2b */ '\'', '*', NOP, NOP, '\'', '*', NOP, NOP, 0x33, 0x00, +/* sc=2c */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01, +/* sc=2d */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01, +/* sc=2e */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01, +/* sc=2f */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01, +/* sc=30 */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01, +/* sc=31 */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01, +/* sc=32 */ 'm', 'M', 0x0D, 0x0D, 'm', 'M', 0x0D, 0x0D, 0x00, 0x01, +/* sc=33 */ ',', ';', NOP, NOP, ',', ';', NOP, NOP, 0x33, 0x00, +/* sc=34 */ '.', ':', NOP, NOP, '.', ':', NOP, NOP, 0x33, 0x00, +/* sc=35 */ '-', '_', 0x1F, 0x1F, '-', '_', 0x1F, 0x1F, 0x00, 0x00, +/* sc=36 */ RSH, RSH, RSH, RSH, RSH, RSH, RSH, RSH, 0xFF, 0x00, +/* sc=37 */ '*', '*', '*', '*', '*', '*', '*', '*', 0x33, 0x00, +/* sc=38 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00, +/* sc=39 */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 0x00, 0x00, +/* sc=3a */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00, +/* sc=3b */ F( 1), F(13), F(25), F(37), S( 1), S(11), S( 1), S(11), 0xFF, 0x00, +/* sc=3c */ F( 2), F(14), F(26), F(38), S( 2), S(12), S( 2), S(12), 0xFF, 0x00, +/* sc=3d */ F( 3), F(15), F(27), F(39), S( 3), S(13), S( 3), S(13), 0xFF, 0x00, +/* sc=3e */ F( 4), F(16), F(28), F(40), S( 4), S(14), S( 4), S(14), 0xFF, 0x00, +/* sc=3f */ F( 5), F(17), F(29), F(41), S( 5), S(15), S( 5), S(15), 0xFF, 0x00, +/* sc=40 */ F( 6), F(18), F(30), F(42), S( 6), S(16), S( 6), S(16), 0xFF, 0x00, +/* sc=41 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00, +/* sc=42 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00, +/* sc=43 */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00, +/* sc=44 */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00, +/* sc=45 */ NLK, NLK, NLK, NLK, NLK, NLK, NLK, NLK, 0xFF, 0x00, +/* sc=46 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00, +/* sc=47 */ F(49), '7', '7', '7', '7', '7', '7', '7', 0x80, 0x02, +/* sc=48 */ F(50), '8', '8', '8', '8', '8', '8', '8', 0x80, 0x02, +/* sc=49 */ F(51), '9', '9', '9', '9', '9', '9', '9', 0x80, 0x02, +/* sc=4a */ F(52), '/', '/', '/', '/', '/', '/', '/', 0x80, 0x02, +/* sc=4b */ F(53), '4', '4', '4', '4', '4', '4', '4', 0x80, 0x02, +/* sc=4c */ NOP, '5', '5', '5', '5', '5', '5', '5', 0x80, 0x02, +/* sc=4d */ F(55), '6', '6', '6', '6', '6', '6', '6', 0x80, 0x02, +/* sc=4e */ F(56), '+', '+', '+', '+', '+', '+', '+', 0x80, 0x02, +/* sc=4f */ F(57), '1', '1', '1', '1', '1', '1', '1', 0x80, 0x02, +/* sc=50 */ F(58), '2', '2', '2', '2', '2', '2', '2', 0x80, 0x02, +/* sc=51 */ F(59), '3', '3', '3', '3', '3', '3', '3', 0x80, 0x02, +/* sc=52 */ F(60), '0', '0', '0', '0', '0', '0', '0', 0x80, 0x02, +/* sc=53 */ 0x7F, '.', '.', '.', '.', '.', '.', '.', 0x00, 0x02, +/* sc=54 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=56 */ '<', '>', 0x1C, 0x1C, '\\', '>', 0x1C, 0x1C, 0x00, 0x00, +/* sc=57 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00, +/* sc=58 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00, +/* sc=59 */ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x02, +/* sc=5a */ RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, 0xFF, 0x00, +/* sc=5b */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x00, +/* sc=5c */ '*', '*', '*', '*', '*', '*', '*', '*', 0x00, 0x00, +/* sc=5d */ RALT, RALT, RALT, RALT, RALT, RALT, RALT, RALT, 0xFF, 0x00, +/* sc=5e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00, +/* sc=5f */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00, +/* sc=60 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00, +/* sc=61 */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00, +/* sc=62 */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00, +/* sc=63 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00, +/* sc=64 */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00, +/* sc=65 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00, +/* sc=66 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00, +/* sc=67 */ F(54), F(54), F(54), F(54), F(54), F(54), F(54), F(54), 0xFF, 0x00, +/* sc=68 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00, +}; + +#else + +keymap_t key_map = { 107, /* US iso8859 keymap */ +/* alt + * scan cntrl alt alt cntrl + * code base shift cntrl shift alt shift cntrl shift spcl flgs + * --------------------------------------------------------------------------- + */ +/* sc=00 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=01 */ 0x1B, 0x1B, NOP, NOP, 0x1B, 0x1B, NOP, NOP, 0x33, 0x00, +/* sc=02 */ '1', '!', NOP, NOP, '1', '!', NOP, NOP, 0x33, 0x00, +/* sc=03 */ '2', '@', 0x00, 0x00, '2', '@', 0x00, 0x00, 0x00, 0x00, +/* sc=04 */ '3', '#', NOP, NOP, '3', '#', NOP, NOP, 0x33, 0x00, +/* sc=05 */ '4', '$', NOP, NOP, '4', '$', NOP, NOP, 0x33, 0x00, +/* sc=06 */ '5', '%', NOP, NOP, '5', '%', NOP, NOP, 0x33, 0x00, +/* sc=07 */ '6', '^', 0x1E, 0x1E, '6', '^', 0x1E, 0x1E, 0x00, 0x00, +/* sc=08 */ '7', '&', NOP, NOP, '7', '&', NOP, NOP, 0x33, 0x00, +/* sc=09 */ '8', '*', NOP, NOP, '8', '*', NOP, NOP, 0x33, 0x00, +/* sc=0a */ '9', '(', NOP, NOP, '9', '(', NOP, NOP, 0x33, 0x00, +/* sc=0b */ '0', ')', NOP, NOP, '0', ')', NOP, NOP, 0x33, 0x00, +/* sc=0c */ '-', '_', 0x1F, 0x1F, '-', '_', 0x1F, 0x1F, 0x00, 0x00, +/* sc=0d */ '=', '+', NOP, NOP, '=', '+', NOP, NOP, 0x33, 0x00, +/* sc=0e */ 0x08, 0x08, 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00, +/* sc=0f */ 0x09, 0x08, NOP, NOP, 0x09, 0x08, NOP, NOP, 0x33, 0x00, +/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01, +/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01, +/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01, +/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01, +/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01, +/* sc=15 */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01, +/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01, +/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01, +/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01, +/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01, +/* sc=1a */ '[', '{', 0x1B, 0x1B, '[', '{', 0x1B, 0x1B, 0x00, 0x00, +/* sc=1b */ ']', '}', 0x1D, 0x1D, ']', '}', 0x1D, 0x1D, 0x00, 0x00, +/* sc=1c */ 0x0D, 0x0D, 0x0A, 0x0A, 0x0D, 0x0D, 0x0A, 0x0A, 0x00, 0x00, +/* sc=1d */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00, +/* sc=1e */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01, +/* sc=1f */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01, +/* sc=20 */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01, +/* sc=21 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01, +/* sc=22 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01, +/* sc=23 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01, +/* sc=24 */ 'j', 'J', 0x0A, 0x0A, 'j', 'J', 0x0A, 0x0A, 0x00, 0x01, +/* sc=25 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01, +/* sc=26 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01, +/* sc=27 */ ';', ':', NOP, NOP, ';', ':', NOP, NOP, 0x33, 0x00, +/* sc=28 */ '\'', '"', NOP, NOP, '\'', '"', NOP, NOP, 0x33, 0x00, +/* sc=29 */ '`', '~', NOP, NOP, '`', '~', NOP, NOP, 0x33, 0x00, +/* sc=2a */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00, +/* sc=2b */ '\\', '|', 0x1C, 0x1C, '\\', '|', 0x1C, 0x1C, 0x00, 0x00, +/* sc=2c */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01, +/* sc=2d */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01, +/* sc=2e */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01, +/* sc=2f */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01, +/* sc=30 */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01, +/* sc=31 */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01, +/* sc=32 */ 'm', 'M', 0x0D, 0x0D, 'm', 'M', 0x0D, 0x0D, 0x00, 0x01, +/* sc=33 */ ',', '<', NOP, NOP, ',', '<', NOP, NOP, 0x33, 0x00, +/* sc=34 */ '.', '>', NOP, NOP, '.', '>', NOP, NOP, 0x33, 0x00, +/* sc=35 */ '/', '?', NOP, NOP, '/', '?', NOP, NOP, 0x33, 0x00, +/* sc=36 */ RSH, RSH, RSH, RSH, RSH, RSH, RSH, RSH, 0xFF, 0x00, +/* sc=37 */ '*', '*', 0x0A, 0x0A, '*', '*', 0x0A, 0x0A, 0x33, 0x00, +/* sc=38 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00, +/* sc=39 */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 0x00, 0x00, +/* sc=3a */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00, +/* sc=3b */ F( 1), F(13), F(25), F(37), S( 1), S(11), S( 1), S(11), 0xFF, 0x00, +/* sc=3c */ F( 2), F(14), F(26), F(38), S( 2), S(12), S( 2), S(12), 0xFF, 0x00, +/* sc=3d */ F( 3), F(15), F(27), F(39), S( 3), S(13), S( 3), S(13), 0xFF, 0x00, +/* sc=3e */ F( 4), F(16), F(28), F(40), S( 4), S(14), S( 4), S(14), 0xFF, 0x00, +/* sc=3f */ F( 5), F(17), F(29), F(41), S( 5), S(15), S( 5), S(15), 0xFF, 0x00, +/* sc=40 */ F( 6), F(18), F(30), F(42), S( 6), S(16), S( 6), S(16), 0xFF, 0x00, +/* sc=41 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00, +/* sc=42 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00, +/* sc=43 */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00, +/* sc=44 */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00, +/* sc=45 */ NLK, NLK, NLK, NLK, NLK, NLK, NLK, NLK, 0xFF, 0x00, +/* sc=46 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00, +/* sc=47 */ F(49), '7', '7', '7', '7', '7', '7', '7', 0x80, 0x02, +/* sc=48 */ F(50), '8', '8', '8', '8', '8', '8', '8', 0x80, 0x02, +/* sc=49 */ F(51), '9', '9', '9', '9', '9', '9', '9', 0x80, 0x02, +/* sc=4a */ F(52), '-', '-', '-', '-', '-', '-', '-', 0x80, 0x02, +/* sc=4b */ F(53), '4', '4', '4', '4', '4', '4', '4', 0x80, 0x02, +/* sc=4c */ NOP, '5', '5', '5', '5', '5', '5', '5', 0x80, 0x02, +/* sc=4d */ F(55), '6', '6', '6', '6', '6', '6', '6', 0x80, 0x02, +/* sc=4e */ F(56), '+', '+', '+', '+', '+', '+', '+', 0x80, 0x02, +/* sc=4f */ F(57), '1', '1', '1', '1', '1', '1', '1', 0x80, 0x02, +/* sc=50 */ F(58), '2', '2', '2', '2', '2', '2', '2', 0x80, 0x02, +/* sc=51 */ F(59), '3', '3', '3', '3', '3', '3', '3', 0x80, 0x02, +/* sc=52 */ F(60), '0', '0', '0', '0', '0', '0', '0', 0x80, 0x02, +/* sc=53 */ 0x7F, '.', 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00, 0x02, +/* sc=54 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=56 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=57 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00, +/* sc=58 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00, +/* sc=59 */ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, +/* sc=5a */ RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, 0xFF, 0x00, +/* sc=5b */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x00, +/* sc=5c */ '*', '*', '*', '*', '*', '*', '*', '*', 0x00, 0x00, +/* sc=5d */ RALT, RALT, RALT, RALT, RALT, RALT, RALT, RALT, 0xFF, 0x00, +/* sc=5e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00, +/* sc=5f */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00, +/* sc=60 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00, +/* sc=61 */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00, +/* sc=62 */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00, +/* sc=63 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00, +/* sc=64 */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00, +/* sc=65 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00, +/* sc=66 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00, +/* sc=67 */ F(54), F(54), F(54), F(54), F(54), F(54), F(54), F(54), 0xFF, 0x00, +/* sc=68 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00, +}; + +#endif + +fkeytab_t fkey_tab[60] = { +/* 00-03 */ {"\033[M", 3}, {"\033[N", 3}, {"\033[O", 3}, {"\033[P", 3}, +/* 04-07 */ {"\033[Q", 3}, {"\033[R", 3}, {"\033[S", 3}, {"\033[T", 3}, +/* 08-0B */ {"\033[U", 3}, {"\033[V", 3}, {"\033[W", 3}, {"\033[X", 3}, +/* 0C-0F */ {"\033[W", 3}, {"\033[X", 3}, {"\033[Y", 3}, {"\033[Z", 3}, +/* 10-13 */ {"\033[a", 3}, {"\033[b", 3}, {"\033[c", 3}, {"\033[d", 3}, +/* 14-17 */ {"\033[e", 3}, {"\033[f", 3}, {"\033[g", 3}, {"\033[h", 3}, +/* 18-1B */ {"\033[g", 3}, {"\033[h", 3}, {"\033[i", 3}, {"\033[j", 3}, +/* 1C-1F */ {"\033[k", 3}, {"\033[l", 3}, {"\033[m", 3}, {"\033[n", 3}, +/* 20-23 */ {"\033[o", 3}, {"\033[p", 3}, {"\033[q", 3}, {"\033[r", 3}, +/* 24-27 */ {"\033[g", 3}, {"\033[h", 3}, {"\033[i", 3}, {"\033[j", 3}, +/* 28-2B */ {"\033[k", 3}, {"\033[l", 3}, {"\033[m", 3}, {"\033[n", 3}, +/* 2C-2F */ {"\033[o", 3}, {"\033[p", 3}, {"\033[q", 3}, {"\033[r", 3}, +/* 30-33 */ {"\033[H", 3}, {"\033[A", 3}, {"\033[I", 3}, {"-" , 1}, +/* 34-37 */ {"\033[D", 3}, {"\177" , 1}, {"\033[C", 3}, {"+" , 1}, +/* 38-3B */ {"\033[F", 3}, {"\033[B", 3}, {"\033[G", 3}, {"\033[L", 3} +}; diff --git a/sys/i386/isa/syscons.c b/sys/i386/isa/syscons.c new file mode 100644 index 000000000000..6081c6522bb7 --- /dev/null +++ b/sys/i386/isa/syscons.c @@ -0,0 +1,2128 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz and Don Ahn. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/* + * Heavily modified by Søren Schmidt (sos@kmd-ac.dk) to provide: + * + * virtual consoles, SYSV ioctl's, ANSI emulation + * + * @(#)syscons.c 0.2 930402 + * + * Modified further to provide full (updated) pccons emulation and + * hooks for init_main.c. Jordan Hubbard, 930725 + * + */ + +#include "param.h" +#include "conf.h" +#include "ioctl.h" +#include "proc.h" +#include "user.h" +#include "tty.h" +#include "uio.h" +#include "callout.h" +#include "systm.h" +#include "kernel.h" +#include "syslog.h" +#include "errno.h" +#include "console.h" +#include "malloc.h" +#include "i386/isa/icu.h" +#include "i386/isa/isa.h" +#include "i386/isa/isa_device.h" +#include "i386/include/pc/display.h" +#include "i386/i386/cons.h" +#include "machine/psl.h" +#include "machine/frame.h" +#include "sc.h" +#include "ddb.h" +#include "iso8859.font" +#include "kbdtables.h" +/*#include "asm.h"*/ + +#if NSC > 0 +#ifndef NCONS +#define NCONS 12 +#endif + +/* status flags */ +#define LOCK_KEY_MASK 0x00007 +#define UNKNOWN_MODE 0x00010 +#define KBD_RAW_MODE 0x00020 +#define SWITCH_WAIT_REL 0x00040 +#define SWITCH_WAIT_ACQ 0x00080 + +/* virtual video memory addresses */ +#define MONO_BUF 0xFE0B0000 +#define CGA_BUF 0xFE0B8000 +#define VGA_BUF 0xFE0A0000 +#define VIDEOMEM 0x000A0000 + +/* misc defines */ +#define MAX_ESC_PAR 2 +#define TEXT80x25 1 +#define TEXT80x50 2 +#define COL 80 +#define ROW 25 +#ifndef XTALSPEED +#define XTALSPEED 1193182 /* should be in isa.h */ +#endif + +/* defines related to hardware addresses */ +#define MONO_BASE 0x3B4 /* crt controller base mono */ +#define COLOR_BASE 0x3D4 /* crt controller base color */ +#define ATC 0x3C0 /* attribute controller */ +#define TSIDX 0x3C4 /* timing sequencer idx */ +#define TSREG 0x3C5 /* timing sequencer data */ +#define PIXMASK 0x3C6 /* pixel write mask */ +#define PALRADR 0x3C7 /* palette read address */ +#define PALWADR 0x3C8 /* palette write address */ +#define PALDATA 0x3C9 /* palette data register */ +#define GDCIDX 0x3CE /* graph data controller idx */ +#define GDCREG 0x3CF /* graph data controller data */ + +typedef struct scr_stat { + u_short *crt_base; /* address of screen memory */ + u_short *scr; /* buffer when off screen */ + u_short *crtat; /* cursor address */ + int esc; /* processing escape sequence */ + int n_par; /* # of parameters to ESC */ + int last_par; /* last parameter # */ + int par[MAX_ESC_PAR]; /* contains ESC parameters */ + int posx; /* current X position */ + int posy; /* current Y position */ + int max_posx; /* X size */ + int max_posy; /* X size */ + int attr; /* current attributes */ + int std_attr; /* normal attributes */ + int rev_attr; /* reverse attributes */ + u_char border; /* border color */ + u_short bell_duration; + u_short bell_pitch; + u_short status; /* status (bitfield) */ + u_short mode; /* mode */ + pid_t pid; /* pid of controlling proc */ + struct proc *proc; /* proc* of controlling proc */ + struct vt_mode smode; /* switch mode */ + } scr_stat; + +static scr_stat cons_scr_stat[NCONS]; +static scr_stat *cur_scr_stat = &cons_scr_stat[0]; +static scr_stat *new_scp, *old_scp; +static int switch_in_progress = 0; + +u_short *Crtat = (u_short *)MONO_BUF; +static u_short *crtat = 0; +static u_int crtc_addr = MONO_BASE; +static u_char shfts = 0, ctls = 0, alts = 0; +static char palette[3*256]; +static const u_int n_fkey_tab = sizeof(fkey_tab) / sizeof(*fkey_tab); +static int cur_cursor_pos = -1; +static char in_putc, nx_scr; +static char saved_console = -1; /* saved console number */ +static long blank_time = 0; /* screen saver timout value */ +static scrmap_t scr_map; + +struct tty pccons[NCONS]; +struct tty *cur_pccons = &pccons[0]; +struct tty *new_pccons; + +extern int hz; +extern struct timeval time; + +#define CSF_ACTIVE 0x1 /* timeout active */ +#define CSF_POLLING 0x2 /* polling for input */ + +struct pcconsoftc { + char cs_flags; + char cs_lastc; /* last char sent */ + int cs_timo; /* timeouts since interrupt */ + u_long cs_wedgecnt; /* times restarted */ + } pcconsoftc = {0, 0, 0, 0}; + + +/* special characters */ +#define bs 8 +#define lf 10 +#define cr 13 +#define cntlc 3 +#define del 0177 +#define cntld 4 + +/* function prototypes */ +int pcprobe(struct isa_device *dev); +int pcattach(struct isa_device *dev); +int pcopen(dev_t dev, int flag, int mode, struct proc *p); +int pcclose(dev_t dev, int flag, int mode, struct proc *p); +int pcread(dev_t dev, struct uio *uio, int flag); +int pcwrite(dev_t dev, struct uio *uio, int flag); +int pcparam(struct tty *tp, struct termios *t); +int pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p); +int pcxint(dev_t dev); +int pcstart(struct tty *tp); +int pccnprobe(struct consdev *cp); +int pccninit(struct consdev *cp); +int pccnputc(dev_t dev, char c); +int pccngetc(dev_t dev); +int scintr(dev_t dev, int irq, int cpl); +void scrn_saver(int test); +static struct tty *get_pccons(dev_t dev); +static scr_stat *get_scr_stat(dev_t dev); +static int get_scr_num(scr_stat *scp); +static void cursor_shape(int start, int end); +static void cursor_pos(void); +static void clear_screen(scr_stat *scp); +static switch_scr(u_int next_scr); +static void exchange_scr(void); +static void move_crsr(scr_stat *scp, u_int x, u_int y); +static void move_up(u_short *s, u_short *d, u_int len); +static void move_down(u_short *s, u_short *d, u_int len); +static void scan_esc(scr_stat *scp, u_char c); +static void ansi_put(scr_stat *scp, u_char c); +void consinit(void); +static void sput(u_char c, u_char ca); +static u_char *get_fstr(u_int c, u_int *len); +static update_leds(int which); +void reset_cpu(void); +u_int sgetc(int noblock); +int pcmmap(dev_t dev, int offset, int nprot); +int getchar(void); +static void kbd_wait(void); +static void kbd_cmd(u_char command); +static void set_mode(scr_stat *scp); +static void set_border(int color); +static load_font(int segment, int size, char* font); +static void save_palette(void); +static void load_palette(void); +static change_winsize(struct tty *tp, int x, int y); + +struct isa_driver scdriver = { + pcprobe, pcattach, "sc", + }; + + +int pcprobe(struct isa_device *dev) +{ + u_char c; + int i, again = 0; + + /* Enable interrupts and keyboard controller */ + kbd_wait(); + outb(KB_STAT, KB_WRITE); + kbd_cmd(0x4D); + + /* Start keyboard stuff RESET */ + kbd_cmd(KB_RESET); + while ((c=inb(KB_DATA)) != KB_ACK) { + if ((c == 0xFE) || (c == 0xFF)) { + if (!again) + printf("KEYBOARD disconnected: RECONNECT \n"); + kbd_cmd(KB_RESET); + again = 1; + } + } + /* + * pick up keyboard reset return code SOS + * some keyboards / controllers hangs if this is enabled + */ + /* while ((c=inb(KB_DATA))!=0xAA); */ + return 1; +} + + +int pcattach(struct isa_device *dev) +{ + scr_stat *scp; + int i; + + if (crtc_addr == MONO_BASE) + printf("VGA mono"); + else + printf("VGA color"); + + if (NCONS > 1) + printf(" <%d virtual consoles>\n", NCONS); + else + printf("\n"); + save_palette(); + load_font(0, 16, font_8x16); + load_font(1, 8, font_8x8); + for (i = 0; i < NCONS; i++) { + scp = &cons_scr_stat[i]; + scp->mode = TEXT80x25; + scp->scr = (u_short *)malloc(COL * ROW * 2, M_DEVBUF, M_NOWAIT); + scp->std_attr = (FG_LIGHTGREY | BG_BLACK) << 8; + scp->rev_attr = (FG_BLACK | BG_LIGHTGREY) << 8; + scp->attr = scp->std_attr; + scp->border = BG_BLACK; + scp->esc = 0; + scp->max_posx = COL; + scp->max_posy = ROW; + scp->bell_pitch = 800; + scp->bell_duration = 10; + scp->status = 0; + scp->pid = 0; + scp->proc = NULL; + scp->smode.mode = VT_AUTO; + if (i > 0) { + scp->crt_base = scp->crtat = scp->scr; + fillw(scp->attr | ' ', scp->scr, COL * ROW); + } + } + cursor_pos(); +} + + +static struct tty *get_pccons(dev_t dev) +{ + int i = minor(dev); + + if (i >= NCONS) + return(NULL); + return(&pccons[i]); +} + + +static scr_stat *get_scr_stat(dev_t dev) +{ + int i = minor(dev); + + if (i >= NCONS) + return(NULL); + return(&cons_scr_stat[i]); +} + + +static int get_scr_num(scr_stat *scp) /* allways call with legal scp !! */ +{ + int i = 0; + + while ((i < NCONS) && (cur_scr_stat != &cons_scr_stat[i])) i++; + return i; +} + +pcopen(dev_t dev, int flag, int mode, struct proc *p) +{ + struct tty *tp = get_pccons(dev); + + if (!tp) + return(ENXIO); + tp->t_oproc = pcstart; + tp->t_param = pcparam; + tp->t_dev = dev; + if ((tp->t_state & TS_ISOPEN) == 0) { + tp->t_state |= TS_WOPEN; + ttychars(tp); + tp->t_iflag = TTYDEF_IFLAG; + tp->t_oflag = TTYDEF_OFLAG; + tp->t_cflag = TTYDEF_CFLAG; + tp->t_lflag = TTYDEF_LFLAG; + tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; + pcparam(tp, &tp->t_termios); + ttsetwater(tp); + } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) + return(EBUSY); + tp->t_state |= TS_CARR_ON; + return((*linesw[tp->t_line].l_open)(dev, tp)); +} + + +pcclose(dev_t dev, int flag, int mode, struct proc *p) +{ + struct tty *tp = get_pccons(dev); + struct scr_stat *scp; + + if (!tp) + return(ENXIO); + scp = get_scr_stat(tp->t_dev); + scp->pid = 0; + scp->proc = NULL; + scp->smode.mode = VT_AUTO; + (*linesw[tp->t_line].l_close)(tp, flag); + ttyclose(tp); + return(0); +} + + +pcread(dev_t dev, struct uio *uio, int flag) +{ + struct tty *tp = get_pccons(dev); + + if (!tp) + return(ENXIO); + return((*linesw[tp->t_line].l_read)(tp, uio, flag)); +} + + +pcwrite(dev_t dev, struct uio *uio, int flag) +{ + struct tty *tp = get_pccons(dev); + + if (!tp) + return(ENXIO); + return((*linesw[tp->t_line].l_write)(tp, uio, flag)); +} + + +/* + * Got a console interrupt, keyboard action ! + * Catch the character, and see who it goes to. + */ +scintr(dev_t dev, int irq, int cpl) +{ + int c, len; + u_char *cp; + + scrn_saver(0); + c = sgetc(1); + if (c & 0x100) + return; + if (pcconsoftc.cs_flags & CSF_POLLING) + return; + if (c < 0x100) + (*linesw[cur_pccons->t_line].l_rint)(c & 0xFF, cur_pccons); + else if (cp = get_fstr((u_int)c, (u_int *)&len)) { + while (len-- > 0) + (*linesw[cur_pccons->t_line].l_rint) + (*cp++ & 0xFF, cur_pccons); + } +} + + +/* + * Set line parameters + */ +pcparam(struct tty *tp, struct termios *t) +{ + int cflag = t->c_cflag; + + /* and copy to tty */ + tp->t_ispeed = t->c_ispeed; + tp->t_ospeed = t->c_ospeed; + tp->t_cflag = cflag; + return(0); +} + + +pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) +{ + int i, error; + struct tty *tp; + struct syscframe *fp; + scr_stat *scp; + + tp = get_pccons(dev); + if (!tp) + return(ENXIO); + scp = get_scr_stat(tp->t_dev); + + switch (cmd) { /* process console hardware related ioctl's */ + + case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */ + blank_time = *(int*)data; + return 0; + + case CONS_80x25TEXT: /* set 80x25 text mode */ + scp->mode = TEXT80x25; + scp->max_posy = 25; + set_mode(scp); + clear_screen(scp); + change_winsize(tp, scp->max_posx, scp->max_posy); + free(scp->scr, M_DEVBUF); + scp->scr = (u_short *)malloc(scp->max_posx*scp->max_posy*2, + M_DEVBUF, M_NOWAIT); + return 0; + + case CONS_80x50TEXT: /* set 80x50 text mode */ + scp->mode = TEXT80x50; + scp->max_posy = 50; + set_mode(scp); + clear_screen(scp); + change_winsize(tp, scp->max_posx, scp->max_posy); + free(scp->scr, M_DEVBUF); + scp->scr = (u_short *)malloc(scp->max_posx*scp->max_posy*2, + M_DEVBUF, M_NOWAIT); + return 0; + + case CONS_GETINFO: /* get current (virtual) console info */ + if (*data == sizeof(struct vid_info)) { + vid_info_t *ptr = (vid_info_t*)data; + ptr->m_num = get_scr_num(scp); + ptr->mv_col = scp->posx; + ptr->mv_row = scp->posy; + ptr->mv_csz = scp->max_posx; + ptr->mv_rsz = scp->max_posy; + ptr->mv_norm.fore = (scp->std_attr & 0x0f00)>>8; + ptr->mv_norm.back = (scp->std_attr & 0xf000)>>12; + ptr->mv_rev.fore = (scp->rev_attr & 0x0f00)>>8; + ptr->mv_rev.back = (scp->rev_attr & 0xf000)>>12; + ptr->mv_grfc.fore = 0; /* not supported */ + ptr->mv_grfc.back = 0; /* not supported */ + ptr->mv_ovscan = scp->border; + ptr->mk_keylock = scp->status & LOCK_KEY_MASK; + return 0; + } + return EINVAL; + + case VT_SETMODE: /* set screen switcher mode */ + bcopy(data, &scp->smode, sizeof(struct vt_mode)); + if (scp->smode.mode == VT_PROCESS) { + scp->proc = p; + scp->pid = scp->proc->p_pid; + } + return 0; + + case VT_GETMODE: /* get screen switcher mode */ + bcopy(&scp->smode, data, sizeof(struct vt_mode)); + return 0; + + case VT_RELDISP: /* screen switcher ioctl */ + switch(*data) { + case VT_FALSE: /* user refuses to release screen, abort */ + if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) { + old_scp->status &= ~SWITCH_WAIT_REL; + switch_in_progress = 0; + return 0; + } + return EINVAL; + + case VT_TRUE: /* user has released screen, go on */ + if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) { + scp->status &= ~SWITCH_WAIT_REL; + exchange_scr(); + if (new_scp->smode.mode == VT_PROCESS) { + new_scp->status |= SWITCH_WAIT_ACQ; + psignal(new_scp->proc, + new_scp->smode.acqsig); + } + else + switch_in_progress = 0; + return 0; + } + return EINVAL; + + case VT_ACKACQ: /* acquire acknowledged, switch completed */ + if (scp == new_scp && (scp->status & SWITCH_WAIT_ACQ)) { + scp->status &= ~SWITCH_WAIT_ACQ; + switch_in_progress = 0; + return 0; + } + return EINVAL; + + default: + return EINVAL; + } + /* NOT REACHED */ + + case VT_OPENQRY: /* return free virtual cons, allways current */ + *data = get_scr_num(scp); + return 0; + + case VT_ACTIVATE: /* switch to screen *data */ + return switch_scr((*data) - 1); + + case VT_WAITACTIVE: /* wait for switch to occur */ + if (*data > NCONS) + return EINVAL; + if (minor(dev) == (*data) - 1) + return 0; + if (*data == 0) { + if (scp == cur_scr_stat) + return 0; + while ((error=tsleep(&scp->smode, + PZERO|PCATCH, "waitvt", 0)) + == ERESTART) ; + } + else + while ((error=tsleep(&cons_scr_stat[*data].smode, + PZERO|PCATCH, "waitvt", 0)) + == ERESTART) ; + return error; + + case KDENABIO: /* allow io operations */ + fp = (struct syscframe *)p->p_regs; + fp->sf_eflags |= PSL_IOPL; + return 0; + + case KDDISABIO: /* disallow io operations (default) */ + fp = (struct syscframe *)p->p_regs; + fp->sf_eflags &= ~PSL_IOPL; + return 0; + + case KDSETMODE: /* set current mode of this (virtual) console */ + switch (*data) { + case KD_TEXT: /* switch to TEXT (known) mode */ + /* restore fonts & palette ! */ + load_font(0, 16, font_8x16); + load_font(1, 8, font_8x8); + load_palette(); + /* FALL THROUGH */ + + case KD_TEXT1: /* switch to TEXT (known) mode */ + /* no restore fonts & palette */ + scp->status &= ~UNKNOWN_MODE; + set_mode(scp); + clear_screen(scp); + return 0; + + case KD_GRAPHICS:/* switch to GRAPHICS (unknown) mode */ + scp->status |= UNKNOWN_MODE; + return 0; + default: + return EINVAL; + } + /* NOT REACHED */ + + case KDGETMODE: /* get current mode of this (virtual) console */ + *data = (scp->status & UNKNOWN_MODE) ? KD_GRAPHICS : KD_TEXT; + return 0; + + case KDSBORDER: /* set border color of this (virtual) console */ + scp->border = *data; + if (scp == cur_scr_stat) + set_border(scp->border); + return 0; + + case KDSKBSTATE: /* set keyboard state (locks) */ + if (*data >= 0 && *data < 4) { + scp->status &= ~LOCK_KEY_MASK; + scp->status |= *data; + if (scp == cur_scr_stat) + update_leds(scp->status & LOCK_KEY_MASK); + return 0; + } + return EINVAL; + + case KDGKBSTATE: /* get keyboard state (locks) */ + *data = scp->status & LOCK_KEY_MASK; + return 0; + + case KDSETRAD: /* set keyboard repeat & delay rates */ + if (*(u_char*)data < 0x80) { + kbd_cmd(KB_SETRAD); + kbd_cmd(*data & 0x7f); + return 0; + } + return EINVAL; + + case KDSKBMODE: /* set keyboard mode */ + switch (*data) { + case K_RAW: /* switch to RAW scancode mode */ + scp->status |= KBD_RAW_MODE; + return 0; + + case K_XLATE: /* switch to XLT ascii mode */ + scp->status &= ~KBD_RAW_MODE; + return 0; + default: + return EINVAL; + } + /* NOT REACHED */ + + case KDGKBMODE: /* get keyboard mode */ + *data = (scp->status & KBD_RAW_MODE) ? K_RAW : K_XLATE; + return 0; + + case KDMKTONE: /* sound the bell */ + if (scp == cur_scr_stat) + sysbeep(scp->bell_pitch, scp->bell_duration); + return 0; + + case KIOCSOUND: /* make tone (*data) hz */ + if (scp == cur_scr_stat) { + if (*(int*)data) { + int pitch = XTALSPEED/(*(int*)data); + /* enable counter 2 */ + outb(0x61, inb(0x61) | 3); + /* set command for counter 2, 2 byte write */ + outb(0x43, 0xb6); + /* set pitch */ + outb(0x42, pitch); + outb(0x42, (pitch>>8)); + } + else { + /* disable counter 2 */ + outb(0x61, inb(0x61) & 0xFC); + } + } + return 0; + + case KDGKBTYPE: /* get keyboard type */ + *data = 0; /* type not known (yet) */ + return 0; + + case KDSETLED: /* set keyboard LED status */ + scp->status &= ~LOCK_KEY_MASK; + scp->status |= (*data & LOCK_KEY_MASK); + if (scp == cur_scr_stat) + update_leds(scp->status & LOCK_KEY_MASK); + return 0; + + case KDGETLED: /* get keyboard LED status */ + *data = scp->status & LOCK_KEY_MASK; + return 0; + + case GETFKEY: /* get functionkey string */ + if (*(u_short*)data < n_fkey_tab) { + fkeyarg_t *ptr = (fkeyarg_t*)data; + bcopy(&fkey_tab[ptr->keynum].str, + ptr->keydef, + fkey_tab[ptr->keynum].len); + ptr->flen = fkey_tab[ptr->keynum].len; + return 0; + } + else + return EINVAL; + + case SETFKEY: /* set functionkey string */ + if (*(u_short*)data < n_fkey_tab) { + fkeyarg_t *ptr = (fkeyarg_t*)data; + bcopy(ptr->keydef, + &fkey_tab[ptr->keynum].str, + min(ptr->flen, MAXFK)); + fkey_tab[ptr->keynum].len = min(ptr->flen, MAXFK); + return 0; + } + else + return EINVAL; + + case GIO_SCRNMAP: /* get output translation table */ + bcopy(&scr_map, data, sizeof(scrmap_t)); + return 0; + + case PIO_SCRNMAP: /* set output translation table */ + bcopy(data, &scr_map, sizeof(scrmap_t)); + return 0; + + case GIO_KEYMAP: /* get keyboard translation table */ + bcopy(&key_map, data, sizeof(key_map)); + return 0; + + case PIO_KEYMAP: /* set keyboard translation table */ + bcopy(data, &key_map, sizeof(key_map)); + return 0; + + case PIO_FONT8x8: /* set 8x8 dot font */ + bcopy(data, &font_8x8, sizeof(fnt8_t)); + load_font(1, 8, font_8x16); + return 0; + + case GIO_FONT8x8: /* get 8x8 dot font */ + bcopy(&font_8x8, data, sizeof(fnt8_t)); + return 0; + + case PIO_FONT8x14: /* set 8x14 dot font */ + bcopy(data, &font_8x14, sizeof(fnt14_t)); + load_font(2, 14, font_8x14); + return 0; + + case GIO_FONT8x14: /* get 8x14 dot font */ + bcopy(&font_8x14, data, sizeof(fnt14_t)); + return 0; + + case PIO_FONT8x16: /* set 8x16 dot font */ + bcopy(data, &font_8x16, sizeof(fnt16_t)); + load_font(0, 16, font_8x16); + return 0; + + case GIO_FONT8x16: /* get 8x16 dot font */ + bcopy(&font_8x16, data, sizeof(fnt16_t)); + return 0; + + case CONSOLE_X_MODE_ON: /* just to be compatible */ + if (saved_console < 0) { + saved_console = get_scr_num(cur_scr_stat); + switch_scr(minor(dev)); + fp = (struct syscframe *)p->p_regs; + fp->sf_eflags |= PSL_IOPL; + scp->status |= UNKNOWN_MODE; + scp->status |= KBD_RAW_MODE; + return 0; + } + return EAGAIN; + + case CONSOLE_X_MODE_OFF:/* just to be compatible */ + fp = (struct syscframe *)p->p_regs; + fp->sf_eflags &= ~PSL_IOPL; + load_font(0, 16, font_8x16); + load_font(1, 8, font_8x8); + scp->status &= ~UNKNOWN_MODE; + set_mode(scp); + clear_screen(scp); + scp->status &= ~KBD_RAW_MODE; + switch_scr(saved_console); + saved_console = -1; + return 0; + + case CONSOLE_X_BELL: + /* + * if set, data is a pointer to a length 2 array of + * integers. data[0] is the pitch in Hz and data[1] + * is the duration in msec. + */ + if (data) + sysbeep(1187500/ ((int*)data)[0], + ((int*)data)[1] * hz/ 3000); + else + sysbeep(0x31b, hz/4); + return 0; + + default: + break; + } + + error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); + if (error >= 0) + return(error); + error = ttioctl(tp, cmd, data, flag); + if (error >= 0) + return(error); + return(ENOTTY); +} + + +pcxint(dev_t dev) +{ + pccons[minor(dev)].t_state &= ~TS_BUSY; + pcconsoftc.cs_timo = 0; + if (pccons[minor(dev)].t_line) + (*linesw[pccons[minor(dev)].t_line].l_start) + (&pccons[minor(dev)]); + else + pcstart(&pccons[minor(dev)]); +} + + +pcstart(struct tty *tp) +{ + int c, s; + scr_stat *scp = get_scr_stat(tp->t_dev); + + s = spltty(); + if (!(tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))) + for (;;) { + if (RB_LEN(&tp->t_out) <= tp->t_lowat) { + if (tp->t_state & TS_ASLEEP) { + tp->t_state &= ~TS_ASLEEP; + wakeup((caddr_t)&tp->t_out); + } + if (tp->t_wsel) { + selwakeup(tp->t_wsel, + tp->t_state & TS_WCOLL); + tp->t_wsel = 0; + tp->t_state &= ~TS_WCOLL; + } + } + if (RB_LEN(&tp->t_out) == 0) + break; + if (scp->status & SLKED) + break; + c = getc(&tp->t_out); + splx(s); + ansi_put(scp, c); + s = spltty(); + } + splx(s); +} + + +pccnprobe(struct consdev *cp) +{ + int maj; + + /* locate the major number */ + for (maj = 0; maj < nchrdev; maj++) + if (cdevsw[maj].d_open == pcopen) + break; + + /* initialize required fields */ + cp->cn_dev = makedev(maj, 0); + cp->cn_tp = &pccons[0]; + cp->cn_pri = CN_INTERNAL; +} + + +pccninit(struct consdev *cp) +{ +} + + +pccnputc(dev_t dev, char c) +{ + int pos; + + if (cur_scr_stat->status & UNKNOWN_MODE) + return; + if (c == '\n') + sput('\r', FG_LIGHTGREY | BG_BLACK); + sput(c, FG_LIGHTGREY | BG_BLACK); + pos = cur_scr_stat->crtat - cur_scr_stat->crt_base; + if (pos != cur_cursor_pos) { + cur_cursor_pos = pos; + outb(crtc_addr,14); + outb(crtc_addr+1,pos >> 8); + outb(crtc_addr,15); + outb(crtc_addr+1,pos&0xff); + } +} + + +pccngetc(dev_t dev) +{ + int c, s; + + s = spltty(); /* block scintr while we poll */ + c = sgetc(0); + splx(s); + if (c == '\r') c = '\n'; + return(c); +} + +#ifndef DONT_BLANK + +void scrn_saver(int test) +{ + u_char val; + static int blanked = 0; + static long time_stamp; + + if (test && blank_time) { + if (time.tv_sec > time_stamp + blank_time) { + blanked = 1; + outb(TSIDX, 0x01); val = inb(TSREG); + outb(TSIDX, 0x01); outb(TSREG, val | 0x20); + } + } + else { + time_stamp = time.tv_sec; + if (blanked) { + blanked = 0; + outb(TSIDX, 0x01); val = inb(TSREG); + outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); + } + } +} + +#else +/* + * alternative screen saver for cards that do not like blanking + * donated by Christoph Robitchko + */ +static u_short cur_cursor_shape; /* remember cursor shape */ + +void scrn_saver(int test) +{ + const char saves[] = {"386BSD"}; + static int blanked = 0; + static u_char *savs[sizeof(saves)-1]; + static int dirx, diry; + static long time_stamp; + static u_short save_cursor; + int f; + scr_stat *scp = cur_scr_stat; + + if (test && blank_time) { + if (time.tv_sec > time_stamp + blank_time) { + if (!blanked) { + bcopy(Crtat, scp->scr, + scp->max_posx * scp->max_posy * 2); + fillw(0x07<<8 | ' ', Crtat, + scp->max_posx * scp->max_posy); + set_border(0); + dirx = (scp->posx ? 1 : -1); + diry = (scp->posy ? + scp->max_posx : -scp->max_posx); + for (f=0; f< sizeof(saves)-1; f++) + savs[f] = (u_char *)Crtat + 2 * + (scp->posx+scp->posy*scp->max_posx); + *(savs[0]) = *saves; + f = scp->max_posy * scp->max_posx + 5; + outb(crtc_addr, 14); + outb(crtc_addr+1, f >> 8); + outb(crtc_addr, 15); + outb(crtc_addr+1, f & 0xff); + save_cursor = cur_cursor_shape; + blanked = 1; + } + if (blanked++ < 4) + return; + blanked = 1; + *(savs[sizeof(saves)-2]) = ' '; + for (f=sizeof(saves)-2; f > 0; f--) + savs[f] = savs[f-1]; + f = (savs[0] - (u_char *)Crtat) / 2; + if ((f % scp->max_posx) == 0 || + (f % scp->max_posx) == scp->max_posx - 1) + dirx = -dirx; + if ((f / scp->max_posx) == 0 || + (f / scp->max_posx) == scp->max_posy - 1) + diry = -diry; + savs[0] += 2*dirx + 2*diry; + for (f=sizeof(saves)-2; f>=0; f--) + *(savs[f]) = saves[f]; + } + } + else { + time_stamp = time.tv_sec; + if (blanked) { + bcopy(scp->scr, Crtat, + scp->max_posx * scp->max_posy * 2); + cur_cursor_pos = -1; + cursor_shape((save_cursor >> 8) & 0xff, + save_cursor & 0xff); + set_border(scp->border); + blanked = 0; + } + } +} + +#endif /* DONT_BLANK */ + +static void cursor_shape(int start, int end) +{ + outb(crtc_addr, 10); + outb(crtc_addr+1, start & 0xFF); + outb(crtc_addr, 11); + outb(crtc_addr+1, end & 0xFF); +#ifdef DONT_BLANK + cur_cursor_shape = ((start & 0xff) << 8) | (end & 0xff); +#endif +} + + +static void cursor_pos(void) +{ + int pos = cur_scr_stat->crtat - cur_scr_stat->crt_base; + + if (cur_scr_stat->status & UNKNOWN_MODE) + return; + scrn_saver(1); + if (pos != cur_cursor_pos) { + cur_cursor_pos = pos; + outb(crtc_addr,14); + outb(crtc_addr+1,pos >> 8); + outb(crtc_addr,15); + outb(crtc_addr+1,pos&0xff); + } + timeout(cursor_pos,0,hz/20); +} + + +static void clear_screen(scr_stat *scp) +{ + move_crsr(scp, 0, 0); + fillw(scp->attr | ' ', scp->crt_base, + scp->max_posx * scp->max_posy); +} + + +static switch_scr(u_int next_scr) +{ + if (in_putc) { /* don't switch if in putc */ + nx_scr = next_scr + 1; + return 0; + } + if (next_scr >= NCONS || switch_in_progress) { + sysbeep(800, hz/4); + return -1; + } + switch_in_progress = 1; + old_scp = cur_scr_stat; + new_scp = &cons_scr_stat[next_scr]; + wakeup(&new_scp->smode); + if (new_scp == old_scp) { + switch_in_progress = 0; + return 0; + } + new_pccons = &pccons[next_scr]; + + /* has controlling process died? */ + if (old_scp->proc && (old_scp->proc != pfind(old_scp->pid))) + old_scp->smode.mode = VT_AUTO; + if (new_scp->proc && (new_scp->proc != pfind(new_scp->pid))) + new_scp->smode.mode = VT_AUTO; + + /* check the modes and switch approbiatly */ + if (old_scp->smode.mode == VT_PROCESS) { + old_scp->status |= SWITCH_WAIT_REL; + psignal(old_scp->proc, old_scp->smode.relsig); + } + else { + exchange_scr(); + if (new_scp->smode.mode == VT_PROCESS) { + new_scp->status |= SWITCH_WAIT_ACQ; + psignal(new_scp->proc, new_scp->smode.acqsig); + } + else + switch_in_progress = 0; + } + return 0; +} + + +static void exchange_scr(void) +{ + bcopy(Crtat, old_scp->scr, old_scp->max_posx * old_scp->max_posy * 2); + old_scp->crt_base = old_scp->scr; + move_crsr(old_scp, old_scp->posx, old_scp->posy); + cur_scr_stat = new_scp; + cur_pccons = new_pccons; + if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE) + shfts = ctls = alts = 0; + update_leds(new_scp->status & LOCK_KEY_MASK); + set_mode(new_scp); + new_scp->crt_base = Crtat; + move_crsr(new_scp, new_scp->posx, new_scp->posy); + bcopy(new_scp->scr, Crtat, new_scp->max_posx * new_scp->max_posy * 2); + nx_scr = 0; +} + + +static void move_crsr(scr_stat *scp, u_int x, u_int y) +{ + if (x < 0 || y < 0 || x >= scp->max_posx || y >= scp->max_posy) + return; + scp->posx = x; + scp->posy = y; + scp->crtat = scp->crt_base + scp->posy * scp->max_posx + scp->posx; +} + + +static void move_up(u_short *s, u_short *d, u_int len) +{ + s += len; + d += len; + while (len-- > 0) + *--d = *--s; +} + + +static void move_down(u_short *s, u_short *d, u_int len) +{ + while (len-- > 0) + *d++ = *s++; +} + + +static void scan_esc(scr_stat *scp, u_char c) +{ + static u_char ansi_col[16] = + {0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15}; + int i, n, m; + u_short *src, *dst, count; + + if (scp->esc == 1) { + switch (c) { + + case '[': /* Start ESC [ sequence */ + scp->esc = 2; + scp->last_par = -1; + for (i = scp->n_par; i < MAX_ESC_PAR; i++) + scp->par[i] = 1; + scp->n_par = 0; + return; + + case 'M': /* Move cursor up 1 line, scroll if at top */ + if (scp->posy > 0) + move_crsr(scp, scp->posx, scp->posy - 1); + else { + move_up(scp->crt_base, + scp->crt_base + scp->max_posx, + (scp->max_posy - 1) * scp->max_posx); + fillw(scp->attr | ' ', + scp->crt_base, scp->max_posx); + } + break; +#if notyet + case 'Q': + scp->esc = 4; + break; +#endif + case 'c': /* Clear screen & home */ + clear_screen(scp); + break; + } + } + else if (scp->esc == 2) { + if (c >= '0' && c <= '9') { + if (scp->n_par < MAX_ESC_PAR) { + if (scp->last_par != scp->n_par) { + scp->last_par = scp->n_par; + scp->par[scp->n_par] = 0; + } + else + scp->par[scp->n_par] *= 10; + scp->par[scp->n_par] += c - '0'; + return; + } + } + scp->n_par = scp->last_par + 1; + switch (c) { + + case ';': + if (scp->n_par < MAX_ESC_PAR) + return; + break; + + case '=': + scp->esc = 3; + scp->last_par = -1; + for (i = scp->n_par; i < MAX_ESC_PAR; i++) + scp->par[i] = 1; + scp->n_par = 0; + return; + + case 'A': /* up n rows */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx, scp->posy - n); + break; + + case 'B': /* down n rows */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx, scp->posy + n); + break; + + case 'C': /* right n columns */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx + n, scp->posy); + break; + + case 'D': /* left n columns */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx - n, scp->posy); + break; + + case 'E': /* cursor to start of line n lines down */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, 0, scp->posy + n); + break; + + case 'F': /* cursor to start of line n lines up */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, 0, scp->posy - n); + break; + + case 'f': /* System V consoles .. */ + case 'H': /* Cursor move */ + if (scp->n_par == 0) + move_crsr(scp, 0, 0); + else if (scp->n_par == 2) + move_crsr(scp, scp->par[1] - 1, scp->par[0] - 1); + break; + + case 'J': /* Clear all or part of display */ + if (scp->n_par == 0) + n = 0; + else + n = scp->par[0]; + switch (n) { + case 0: /* clear form cursor to end of display */ + fillw(scp->attr | ' ', scp->crtat, + scp->crt_base + scp->max_posx * + scp->max_posy - scp->crtat); + break; + case 1: /* clear from beginning of display to cursor */ + fillw(scp->attr | ' ', scp->crt_base, + scp->crtat - scp->crt_base); + break; + case 2: /* clear entire display */ + clear_screen(scp); + break; + } + break; + + case 'K': /* Clear all or part of line */ + if (scp->n_par == 0) + n = 0; + else + n = scp->par[0]; + switch (n) { + case 0: /* clear form cursor to end of line */ + fillw(scp->attr | ' ', scp->crtat, + scp->max_posx - scp->posx); + break; + case 1: /* clear from beginning of line to cursor */ + fillw(scp->attr | ' ', + scp->crtat - (scp->max_posx - scp->posx), + (scp->max_posx - scp->posx) + 1); + break; + case 2: /* clear entire line */ + fillw(scp->attr | ' ', + scp->crtat - (scp->max_posx - scp->posx), + scp->max_posx); + break; + } + break; + + case 'L': /* Insert n lines */ + n = scp->par[0]; if (n < 1) n = 1; + if (n > scp->max_posy - scp->posy) + n = scp->max_posy - scp->posy; + src = scp->crt_base + scp->posy * scp->max_posx; + dst = src + n * scp->max_posx; + count = scp->max_posy - (scp->posy + n); + move_up(src, dst, count * scp->max_posx); + fillw(scp->attr | ' ', src, n * scp->max_posx); + break; + + case 'M': /* Delete n lines */ + n = scp->par[0]; if (n < 1) n = 1; + if (n > scp->max_posy - scp->posy) + n = scp->max_posy - scp->posy; + dst = scp->crt_base + scp->posy * scp->max_posx; + src = dst + n * scp->max_posx; + count = scp->max_posy - (scp->posy + n); + move_down(src, dst, count * scp->max_posx); + src = dst + count * scp->max_posx; + fillw(scp->attr | ' ', src, n * scp->max_posx); + break; + + case 'P': /* Delete n chars */ + n = scp->par[0]; if (n < 1) n = 1; + if (n > scp->max_posx - scp->posx) + n = scp->max_posx - scp->posx; + dst = scp->crtat; + src = dst + n; + count = scp->max_posx - (scp->posx + n); + move_down(src, dst, count); + src = dst + count; + fillw(scp->attr | ' ', src, n); + break; + + case '@': /* Insert n chars */ + n = scp->par[0]; if (n < 1) n = 1; + if (n > scp->max_posx - scp->posx) + n = scp->max_posx - scp->posx; + src = scp->crtat; + dst = src + n; + count = scp->max_posx - (scp->posx + n); + move_up(src, dst, count); + fillw(scp->attr | ' ', src, n); + break; + + case 'S': /* scroll up n lines */ + n = scp->par[0]; if (n < 1) n = 1; + bcopy(scp->crt_base + (scp->max_posx * n), + scp->crt_base, + scp->max_posx * (scp->max_posy - n) * + sizeof(u_short)); + fillw(scp->attr | ' ', + scp->crt_base + scp->max_posx * + (scp->max_posy - 1), + scp->max_posx); + break; + + case 'T': /* scroll down n lines */ + n = scp->par[0]; if (n < 1) n = 1; + bcopy(scp->crt_base, + scp->crt_base + (scp->max_posx * n), + scp->max_posx * (scp->max_posy - n) * + sizeof(u_short)); + fillw(scp->attr | ' ', scp->crt_base, scp->max_posx); + break; + + case 'X': /* delete n characters in line */ + n = scp->par[0]; if (n < 1) n = 1; + fillw(scp->attr | ' ', scp->crt_base + scp->posx + + ((scp->max_posx*scp->posy) * sizeof(u_short)), n); + break; + + case 'Z': /* move n tabs backwards */ + n = scp->par[0]; if (n < 1) n = 1; + if ((i = scp->posx & 0xf8) == scp->posx) + i -= 8*n; + else + i -= 8*(n-1); + if (i < 0) + i = 0; + move_crsr(scp, i, scp->posy); + break; + + case '`': /* move cursor to column n */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, n, scp->posy); + break; + + case 'a': /* move cursor n columns to the right */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx + n, scp->posy); + break; + + case 'd': /* move cursor to row n */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx, n); + break; + + case 'e': /* move cursor n rows down */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx, scp->posy + n); + break; + + case 'm': /* change attribute */ + if (scp->n_par == 0) + n = 0; + else + n = scp->par[0]; + switch (n) { + case 0: /* back to normal */ + scp->attr = scp->std_attr; + break; + case 1: /* highlight (bold) */ + scp->attr &= 0xFF00; + scp->attr |= 0x0800; + break; + case 4: /* highlight (underline) */ + scp->attr &= 0x0F00; + scp->attr |= 0x0800; + break; + case 5: /* blink */ + scp->attr &= 0xFF00; + scp->attr |= 0x8000; + break; + case 7: /* reverse video */ + scp->attr = scp->rev_attr; + break; + case 30: case 31: case 32: case 33: /* set fg color */ + case 34: case 35: case 36: case 37: + scp->attr = (scp->attr & 0xF0FF) + | (ansi_col[(n - 30) & 7] << 8); + break; + case 40: case 41: case 42: case 43: /* set bg color */ + case 44: case 45: case 46: case 47: + scp->attr = (scp->attr & 0x0FFF) + | (ansi_col[(n - 40) & 7] << 12); + break; + } + break; + + case 'x': + if (scp->n_par == 0) + n = 0; + else + n = scp->par[0]; + switch (n) { + case 0: /* reset attributes */ + scp->attr = scp->std_attr = FG_LIGHTGREY << 8; + break; + case 1: /* set ansi background */ + scp->attr = scp->std_attr = + (scp->std_attr & 0x0F00) + | (ansi_col[(scp->par[1])&0x0F] << 12); + break; + case 2: /* set ansi foreground */ + scp->attr = scp->std_attr = + (scp->std_attr & 0xF000) + | (ansi_col[(scp->par[1])&0x0F] << 8); + break; + case 3: /* set ansi attribute directly */ + scp->attr = scp->std_attr = + (scp->par[1] & 0xFF) << 8; + break; + case 5: /* set ansi reverse video background */ + scp->rev_attr = + (scp->rev_attr & 0x0F00) + | (ansi_col[(scp->par[1]) & 0x0F] << 12); + break; + case 6: /* set ansi reverse video foreground */ + scp->rev_attr = + (scp->rev_attr & 0xF000) + | (ansi_col[(scp->par[1]) & 0x0F] << 8); + break; + case 7: /* set ansi reverse video directly */ + scp->rev_attr = (scp->par[1] & 0xFF) << 8; + break; + } + break; + + case 'z': /* switch to (virtual) console n */ + if (scp->n_par == 1) + switch_scr(scp->par[0]); + break; + } + } + else if (scp->esc == 3) { + if (c >= '0' && c <= '9') { + if (scp->n_par < MAX_ESC_PAR) { + if (scp->last_par != scp->n_par) { + scp->last_par = scp->n_par; + scp->par[scp->n_par] = 0; + } + else + scp->par[scp->n_par] *= 10; + scp->par[scp->n_par] += c - '0'; + return; + } + } + scp->n_par = scp->last_par + 1; + switch (c) { + + case ';': + if (scp->n_par < MAX_ESC_PAR) + return; + break; + + case 'A': /* set display border color */ + if (scp->n_par == 1) + scp->border=scp->par[0] & 0xff; + if (scp == cur_scr_stat) + set_border(scp->border); + break; + + case 'B': /* set bell pitch and duration */ + if (scp->n_par == 2) { + scp->bell_pitch = scp->par[0]; + scp->bell_duration = scp->par[1]*10; + } + break; + + case 'C': /* set cursor shape (start & end line) */ + if (scp->n_par == 2) + cursor_shape(scp->par[0], scp->par[1]); + break; + + case 'F': /* set ansi foreground */ + if (scp->n_par == 1) + scp->attr = scp->std_attr = + (scp->std_attr & 0xF000) + | ((scp->par[0] & 0x0F) << 8); + break; + + case 'G': /* set ansi background */ + if (scp->n_par == 1) + scp->attr = scp->std_attr = + (scp->std_attr & 0x0F00) + | ((scp->par[0] & 0x0F) << 12); + break; + + case 'H': /* set ansi reverse video foreground */ + if (scp->n_par == 1) + scp->rev_attr = + (scp->rev_attr & 0xF000) + | ((scp->par[0] & 0x0F) << 8); + break; + + case 'I': /* set ansi reverse video background */ + if (scp->n_par == 1) + scp->rev_attr = + (scp->rev_attr & 0x0F00) + | ((scp->par[0] & 0x0F) << 12); + break; + } + } + scp->esc = 0; +} + + +#define wrtchar(scp, c) ( *scp->crtat = (c), scp->crtat++, scp->posx++ ) + +static void ansi_put(scr_stat *scp, u_char c) +{ + int s; + + if (scp == cur_scr_stat ) + scrn_saver(0); + if (scp->status & UNKNOWN_MODE) + return; + in_putc++; + if (scp->esc) + scan_esc(scp, c); + else switch(c) { + case 0x1B: + scp->esc = 1; + scp->n_par = 0; + break; + case '\t': + do { + wrtchar(scp, scp->attr | ' '); + } while (scp->posx % 8); + break; + case '\b': /* non-destructive backspace */ + if (scp->crtat > scp->crt_base) { + scp->crtat--; + if (scp->posx > 0) + scp->posx--; + else { + scp->posx += scp->max_posx - 1; + scp->posy--; + } + } + break; + case '\r': + move_crsr(scp, 0, scp->posy); + break; + case '\n': + scp->crtat += scp->max_posx; + scp->posy++; + break; + case '\f': + clear_screen(scp); + break; + default: + if (c == 7) { + if (scp == cur_scr_stat) + sysbeep(scp->bell_pitch, scp->bell_duration); + } + /* Print only printables */ + else { + wrtchar(scp, scp->attr | c); + if (scp->posx >= scp->max_posx) { + scp->posx = 0; + scp->posy++; + } + break; + } + } + if (scp->crtat >= scp->crt_base + scp->max_posy * scp->max_posx) { + bcopy(scp->crt_base + scp->max_posx, scp->crt_base, + scp->max_posx * (scp->max_posy - 1) * sizeof(u_short)); + fillw(scp->attr | ' ', + scp->crt_base + scp->max_posx * (scp->max_posy - 1), + scp->max_posx); + scp->crtat -= scp->max_posx; + scp->posy--; + } + s = spltty(); + in_putc--; + splx(s); + if (nx_scr) + switch_scr(nx_scr - 1); +} + + +void consinit(void) +{ + u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/sizeof(u_short), was; + scr_stat *scp; + unsigned cursorat; + int i; + + /* + * catch that once in a blue moon occurence when consinit is called + * TWICE, adding the CGA_BUF offset again -> poooff + * thanks to Christoph Robitchko for finding this one !! + */ + if (crtat != 0) + return; + /* + * Crtat initialized to point to MONO buffer, if not present change + * to CGA_BUF offset. ONLY ADD the difference since locore.s adds + * in the remapped offset at the right time + */ + was = *cp; + *cp = (u_short) 0xA55A; + if (*cp != 0xA55A) { + crtc_addr = MONO_BASE; + } else { + *cp = was; + crtc_addr = COLOR_BASE; + Crtat = Crtat + (CGA_BUF-MONO_BUF)/sizeof(u_short); + } + /* Extract cursor location */ + outb(crtc_addr,14); + cursorat = inb(crtc_addr+1)<<8 ; + outb(crtc_addr,15); + cursorat |= inb(crtc_addr+1); + + crtat = Crtat+ cursorat; + + cons_scr_stat[0].crtat = crtat; + cons_scr_stat[0].crt_base = Crtat; + cons_scr_stat[0].posx = cursorat % COL; + cons_scr_stat[0].posy = cursorat / COL; + cons_scr_stat[0].esc = 0; + cons_scr_stat[0].std_attr = (FG_LIGHTGREY | BG_BLACK) << 8; + cons_scr_stat[0].rev_attr = (FG_BLACK | BG_LIGHTGREY) << 8; + cons_scr_stat[0].attr = (FG_LIGHTGREY | BG_BLACK) << 8; + cons_scr_stat[0].border = BG_BLACK;; + cons_scr_stat[0].max_posx = COL; + cons_scr_stat[0].max_posy = ROW; + cons_scr_stat[0].status = 0; + cons_scr_stat[0].pid = 0; + cons_scr_stat[0].proc = NULL; + cons_scr_stat[0].smode.mode = VT_AUTO; + cons_scr_stat[0].bell_pitch = 800; + cons_scr_stat[0].bell_duration = 10; + clear_screen(&cons_scr_stat[0]); +} + + +static void sput(u_char c, u_char ca) +{ + int i; + scr_stat *scp = &cons_scr_stat[0]; + + if (crtat == 0) + consinit(); + i = scp->attr; + scp->attr = ca << 8; + ansi_put(scp, c); + scp->attr = i; +} + + +static u_char *get_fstr(u_int c, u_int *len) +{ + u_int i; + + if (!(c & FKEY)) + return(NULL); + i = (c & 0xFF) - F_FN; + if (i > n_fkey_tab) + return(NULL); + *len = fkey_tab[i].len; + return(fkey_tab[i].str); +} + + +static update_leds(int which) +{ + u_char xlate_leds[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; + int i; + + kbd_cmd(KB_SETLEDS); /* LED Command */ + kbd_cmd(xlate_leds[which]); + kbd_wait(); +} + + +volatile void reset_cpu(void) +{ + int i; + + while (1) { + kbd_cmd(KB_RESET_CPU); /* Reset Command */ + DELAY(4000000); + kbd_cmd(KB_RESET); /* Keyboard Reset Command */ + } +} + + +/* + * sgetc(noblock) : get a character from the keyboard. + * If noblock = 0 wait until a key is gotten. Otherwise return a 0x100. + */ +u_int sgetc(int noblock) +{ + u_char dt, modifier; + static u_char esc_flag = 0; + u_int state, action; + int i; + struct key_t *key; + +next_code: + kbd_wait(); + /* First see if there is something in the keyboard port */ + if (inb(KB_STAT) & KB_BUF_FULL) + dt = inb(KB_DATA); + else if (noblock) + return(0x100); + else + goto next_code; + + if (cur_scr_stat->status & KBD_RAW_MODE) + return dt; + + /* Check for cntl-alt-del */ + if ((dt == 83) && ctls && alts) + cpu_reset(); + +#if NDDB > 0 + /* Check for cntl-alt-esc */ + if ((dt == 1) && ctls && alts) { + /* if debugger called, try to switch to console 0 */ + if (cur_scr_stat->smode.mode == VT_AUTO && + cons_scr_stat[0].smode.mode == VT_AUTO) + switch_scr(0); + Debugger(); + } +#endif + if (dt == 0xE0 || dt == 0xE1) { + esc_flag = dt; + goto next_code; + } + + if ((dt & 0x7F) >= key_map.n_keys) + goto next_code; + + if (esc_flag == 0xE0) { + switch (dt & 0x7F) { + case 0x2A: /* This may come because the keyboard keeps */ + case 0x36: /* its own caps lock status, we ignore SOS */ + goto next_code; + /* NOT REACHED */ + case 0x1C: /* keypad enter key */ + modifier = 0x59; + break; + case 0x1D: /* right control key */ + modifier = 0x5a; + break; + case 0x35: /* keypad divide key */ + modifier = 0x5b; + break; + case 0x37: /* print scrn key */ + modifier = 0x5c; + break; + case 0x38: /* right alt key (alt gr) */ + modifier = 0x5d; + break; + case 0x47: /* grey home key */ + modifier = 0x5e; + break; + case 0x48: /* grey up arrow key */ + modifier = 0x5f; + break; + case 0x49: /* grey page up key */ + modifier = 0x60; + break; + case 0x4b: /* grey left arrow key */ + modifier = 0x61; + break; + case 0x4d: /* grey right arrow key */ + modifier = 0x62; + break; + case 0x4f: /* grey end key */ + modifier = 0x63; + break; + case 0x50: /* grey down arrow key */ + modifier = 0x64; + break; + case 0x51: /* grey page down key */ + modifier = 0x65; + break; + case 0x52: /* grey insert key */ + modifier = 0x66; + break; + case 0x53: /* grey delete key */ + modifier = 0x67; + break; + default: /* every thing else is ignored */ + goto next_code; + /* NOT REACHED */ + } + dt = (dt & 0x80) | modifier; + } + else if (esc_flag == (u_char)0xE1 && ((dt & 0x7F) == 0x1D)) { + esc_flag = 0x1D; + goto next_code; + } + else if (esc_flag == 0x1D && ((dt & 0x7F) == 0x45)) + dt = (dt & 0x80) | 0x68; + esc_flag = 0; + + state = (shfts ? 1 : 0 ) | (2 * (ctls ? 1 : 0)) | (4 * (alts ? 1 : 0)); + key = &key_map.key[dt & 0x7F]; + if ( ((key->flgs & FLAG_LOCK_C) && (cur_scr_stat->status & CLKED)) + || ((key->flgs & FLAG_LOCK_N) && (cur_scr_stat->status & NLKED)) ) + state ^= 1; + + /* Check for make/break */ + action = key->map[state]; + if (dt & 0x80) { + /* break */ + if (key->spcl & 0x80) { + switch (action) { + case LSH: + shfts &= ~1; + break; + case RSH: + shfts &= ~2; + break; + case LCTR: + ctls &= ~1; + break; + case RCTR: + ctls &= ~2; + break; + case LALT: + alts &= ~1; + break; + case RALT: + alts &= ~2; + break; + } + } + } else { + /* make */ + if (key->spcl & (0x80>>state)) { + switch (action) { + /* LOCKING KEYS */ + case NLK: + if (cur_scr_stat->status & NLKED) + cur_scr_stat->status &= ~NLKED; + else + cur_scr_stat->status |= NLKED; + update_leds(cur_scr_stat->status&LOCK_KEY_MASK); + break; + case CLK: + if (cur_scr_stat->status & CLKED) + cur_scr_stat->status &= ~CLKED; + else + cur_scr_stat->status |= CLKED; + update_leds(cur_scr_stat->status&LOCK_KEY_MASK); + break; + case SLK: + if (cur_scr_stat->status & SLKED) { + cur_scr_stat->status &= ~SLKED; + pcstart(&pccons[get_scr_num(cur_scr_stat)]); + } + else + cur_scr_stat->status |= SLKED; + update_leds(cur_scr_stat->status&LOCK_KEY_MASK); + break; + + /* NON-LOCKING KEYS */ + case LSH: + shfts |= 1; + break; + case RSH: + shfts |= 2; + break; + case LCTR: + ctls |= 1; + break; + case RCTR: + ctls |= 2; + break; + case LALT: + alts |= 1; + break; + case RALT: + alts |= 2; + break; + default: + if (action >= F_SCR && action <= L_SCR) { + switch_scr(action - F_SCR); + break; + } + if (action >= F_FN && action <= L_FN) { + return(action | FKEY); + } + return(action); + } + } + else return(action); + } + goto next_code; +} + +/* -hv- 22-Apr-93: to make init_main more portable */ +void cons_highlight(void) +{ + scr_stat *scp = &cons_scr_stat[0]; + + scp->attr &= 0xFF00; + scp->attr |= 0x0800; +} + +void cons_normal(void) +{ + scr_stat *scp = &cons_scr_stat[0]; + + scp->attr = scp->std_attr; +} + +int getchar(void) +{ + char thechar; + int delay, x; + + pcconsoftc.cs_flags |= CSF_POLLING; + x = splhigh(); + sput('>', FG_RED | BG_BLACK); + thechar = (char) sgetc(0); + pcconsoftc.cs_flags &= ~CSF_POLLING; + splx(x); + switch (thechar) { + default: + if (thechar >= ' ') + sput(thechar, FG_RED | BG_BLACK); + return(thechar); + case cr: + case lf: + sput(cr, FG_RED | BG_BLACK); + sput(lf, FG_RED | BG_BLACK); + return(lf); + case bs: + case del: + sput(bs, FG_RED | BG_BLACK); + sput(' ', FG_RED | BG_BLACK); + sput(bs, FG_RED | BG_BLACK); + return(thechar); + case cntld: + sput('^', FG_RED | BG_BLACK) ; + sput('D', FG_RED | BG_BLACK) ; + sput('\r', FG_RED | BG_BLACK) ; + sput('\n', FG_RED | BG_BLACK) ; + return(0); + } +} + + +int pcmmap(dev_t dev, int offset, int nprot) +{ + if (offset > 0x20000) + return EINVAL; + return i386_btop((VIDEOMEM + offset)); +} + + +static void kbd_wait(void) +{ + int i; + for (i=0; i<10000; i++) + if ((inb(KB_STAT) & KB_READY) == 0) + break; +} + + +static void kbd_cmd(u_char command) +{ + kbd_wait(); + outb(KB_DATA, command); +} + + +static void set_mode(scr_stat *scp) +{ + u_char byte; + + if (scp != cur_scr_stat) + return; + + /* setup video hardware for the given mode */ + switch(scp->mode) { + case TEXT80x25: + outb(crtc_addr, 9); byte = inb(crtc_addr+1); + outb(crtc_addr, 9); outb(crtc_addr+1, byte | 0x0F); + outb(TSIDX, 0x03); outb(TSREG, 0x00); /* select font 0 */ + break; + case TEXT80x50: + outb(crtc_addr, 9); byte = inb(crtc_addr+1); + outb(crtc_addr, 9); outb(crtc_addr+1, (byte & 0xF0) | 0x07); + outb(TSIDX, 0x03); outb(TSREG, 0x05); /* select font 1 */ + break; + default: + return; + } + + /* set border color for this (virtual) console */ + set_border(scp->border); + + /* (re)activate cursor */ + untimeout(cursor_pos, 0); + cursor_pos(); +} + + +static void set_border(int color) +{ + inb(crtc_addr+6); /* reset flip-flop */ + outb(ATC, 0x11); outb(ATC, color); + inb(crtc_addr+6); /* reset flip-flop */ + outb(ATC, 0x20); /* enable Palette */ +} + +static load_font(int segment, int size, char* font) +{ + int ch, line; + u_char val; + + outb(TSIDX, 0x01); val = inb(TSREG); /* blank screen */ + outb(TSIDX, 0x01); outb(TSREG, val | 0x20); + + /* setup vga for loading fonts (graphics plane mode) */ + inb(crtc_addr+6); /* reset flip/flop */ + outb(ATC, 0x30); outb(ATC, 0x01); + outb(TSIDX, 0x02); outb(TSREG, 0x04); + outb(TSIDX, 0x04); outb(TSREG, 0x06); + outb(GDCIDX, 0x04); outb(GDCREG, 0x02); + outb(GDCIDX, 0x05); outb(GDCREG, 0x00); + outb(GDCIDX, 0x06); outb(GDCREG, 0x05); /* addr = a0000, 64kb */ + for (ch=0; ch < 256; ch++) + for (line=0; line < size; line++) + *((char *)atdevbase+(segment*0x4000)+(ch*32)+line) = + font[(ch*size)+line]; + /* setup vga for text mode again */ + inb(crtc_addr+6); /* reset flip/flop */ + outb(ATC, 0x30); outb(ATC, 0x0C); + outb(TSIDX, 0x02); outb(TSREG, 0x03); + outb(TSIDX, 0x04); outb(TSREG, 0x02); + outb(GDCIDX, 0x04); outb(GDCREG, 0x00); + outb(GDCIDX, 0x05); outb(GDCREG, 0x10); + if (crtc_addr == MONO_BASE) { + outb(GDCIDX, 0x06); outb(GDCREG, 0x0A); /* addr = b0000, 32kb */ + } + else { + outb(GDCIDX, 0x06); outb(GDCREG, 0x0E); /* addr = b8000, 32kb */ + } + outb(TSIDX, 0x01); val = inb(TSREG); /* unblank screen */ + outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); +} + + +static void load_palette(void) +{ + int i; + + outb(PIXMASK, 0xFF); /* no pixelmask */ + outb(PALWADR, 0x00); + for (i=0x00; i<0x300; i++) + outb(PALDATA, palette[i]); + inb(crtc_addr+6); /* reset flip/flop */ + outb(ATC, 0x20); /* enable palette */ +} + +static void save_palette(void) +{ + int i; + + outb(PALRADR, 0x00); + for (i=0x00; i<0x300; i++) + palette[i] = inb(PALDATA); + inb(crtc_addr+6); /* reset flip/flop */ +} + + +static change_winsize(struct tty *tp, int x, int y) +{ + if (tp->t_winsize.ws_col != x || tp->t_winsize.ws_row != y) { + tp->t_winsize.ws_col = x; + tp->t_winsize.ws_row = y; + pgsignal(tp->t_pgrp, SIGWINCH, 1); + } +} + +#endif /* NSC */ diff --git a/sys/isa/kbdtables.h b/sys/isa/kbdtables.h new file mode 100644 index 000000000000..013cf59e9b7f --- /dev/null +++ b/sys/isa/kbdtables.h @@ -0,0 +1,265 @@ +/* + * Copyright (C) 1992, 1993 Søren Schmidt + * + * This program is free software; you may redistribute it and/or + * modify it, provided that it retain the above copyright notice + * and the following disclaimer. + * + * 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. + * + * Søren Schmidt Email: sos@kmd-ac.dk + * Tritonvej 36 UUCP: ...uunet!dkuug!kmd-ac!sos + * DK9210 Aalborg SO Phone: +45 9814 8076 + */ + +#if defined(DKKEYMAP) + +keymap_t key_map = { 107, /* DK iso8859 keymap */ +/* alt + * scan cntrl alt alt cntrl + * code base shift cntrl shift alt shift cntrl shift spcl flgs + * --------------------------------------------------------------------------- + */ +/* sc=00 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=01 */ 0x1B, 0x1B, NOP, NOP, 0x1B, 0x1B, NOP, NOP, 0x33, 0x00, +/* sc=02 */ '1', '!', NOP, NOP, '1', '!', NOP, NOP, 0x33, 0x00, +/* sc=03 */ '2', '"', 0x00, 0x00, '@', '"', 0x00, 0x00, 0x00, 0x00, +/* sc=04 */ '3', '#', NOP, NOP, 0x9E, '#', NOP, NOP, 0x33, 0x00, +/* sc=05 */ '4', 0xA4, NOP, NOP, '$', 0xA4, NOP, NOP, 0x33, 0x00, +/* sc=06 */ '5', '%', NOP, NOP, '5', '%', NOP, NOP, 0x33, 0x00, +/* sc=07 */ '6', '&', NOP, NOP, '6', '&', NOP, NOP, 0x33, 0x00, +/* sc=08 */ '7', '/', NOP, NOP, '{', '/', NOP, NOP, 0x33, 0x00, +/* sc=09 */ '8', '(', 0x1B, 0x1B, '[', '(', 0x1B, 0x1B, 0x00, 0x00, +/* sc=0a */ '9', ')', 0x1D, 0x1D, ']', ')', 0x1D, 0x1D, 0x00, 0x00, +/* sc=0b */ '0', '=', NOP, NOP, '}', '=', NOP, NOP, 0x33, 0x00, +/* sc=0c */ '+', '?', NOP, NOP, '+', '?', NOP, NOP, 0x33, 0x00, +/* sc=0d */ '\'', '`', NOP, NOP, '|', '`', NOP, NOP, 0x33, 0x00, +/* sc=0e */ 0x08, 0x08, 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00, +/* sc=0f */ 0x09, 0x08, NOP, NOP, 0x09, 0x08, NOP, NOP, 0x33, 0x00, +/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01, +/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01, +/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01, +/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01, +/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01, +/* sc=15 */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01, +/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01, +/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01, +/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01, +/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01, +/* sc=1a */ 0xE5, 0xC5, NOP, NOP, 0x86, 0x8F, NOP, NOP, 0x33, 0x01, +/* sc=1b */ '"', '^', 0x1E, 0x1E, '~', '^', 0x1E, 0x1E, 0x00, 0x00, +/* sc=1c */ 0x0D, 0x0D, 0x0A, 0x0A, 0x0D, 0x0D, 0x0A, 0x0A, 0x00, 0x00, +/* sc=1d */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00, +/* sc=1e */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01, +/* sc=1f */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01, +/* sc=20 */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01, +/* sc=21 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01, +/* sc=22 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01, +/* sc=23 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01, +/* sc=24 */ 'j', 'J', 0x0A, 0x0A, 'j', 'J', 0x0A, 0x0A, 0x00, 0x01, +/* sc=25 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01, +/* sc=26 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01, +/* sc=27 */ 0xE6, 0xC6, NOP, NOP, 0x91, 0x92, NOP, NOP, 0x33, 0x01, +/* sc=28 */ 0xF8, 0xD8, NOP, NOP, 0x9B, 0x9D, NOP, NOP, 0x33, 0x01, +/* sc=29 */ 0xBD, 0xA7, NOP, NOP, 0xBD, 0xA7, NOP, NOP, 0x33, 0x00, +/* sc=2a */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00, +/* sc=2b */ '\'', '*', NOP, NOP, '\'', '*', NOP, NOP, 0x33, 0x00, +/* sc=2c */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01, +/* sc=2d */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01, +/* sc=2e */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01, +/* sc=2f */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01, +/* sc=30 */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01, +/* sc=31 */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01, +/* sc=32 */ 'm', 'M', 0x0D, 0x0D, 'm', 'M', 0x0D, 0x0D, 0x00, 0x01, +/* sc=33 */ ',', ';', NOP, NOP, ',', ';', NOP, NOP, 0x33, 0x00, +/* sc=34 */ '.', ':', NOP, NOP, '.', ':', NOP, NOP, 0x33, 0x00, +/* sc=35 */ '-', '_', 0x1F, 0x1F, '-', '_', 0x1F, 0x1F, 0x00, 0x00, +/* sc=36 */ RSH, RSH, RSH, RSH, RSH, RSH, RSH, RSH, 0xFF, 0x00, +/* sc=37 */ '*', '*', '*', '*', '*', '*', '*', '*', 0x33, 0x00, +/* sc=38 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00, +/* sc=39 */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 0x00, 0x00, +/* sc=3a */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00, +/* sc=3b */ F( 1), F(13), F(25), F(37), S( 1), S(11), S( 1), S(11), 0xFF, 0x00, +/* sc=3c */ F( 2), F(14), F(26), F(38), S( 2), S(12), S( 2), S(12), 0xFF, 0x00, +/* sc=3d */ F( 3), F(15), F(27), F(39), S( 3), S(13), S( 3), S(13), 0xFF, 0x00, +/* sc=3e */ F( 4), F(16), F(28), F(40), S( 4), S(14), S( 4), S(14), 0xFF, 0x00, +/* sc=3f */ F( 5), F(17), F(29), F(41), S( 5), S(15), S( 5), S(15), 0xFF, 0x00, +/* sc=40 */ F( 6), F(18), F(30), F(42), S( 6), S(16), S( 6), S(16), 0xFF, 0x00, +/* sc=41 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00, +/* sc=42 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00, +/* sc=43 */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00, +/* sc=44 */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00, +/* sc=45 */ NLK, NLK, NLK, NLK, NLK, NLK, NLK, NLK, 0xFF, 0x00, +/* sc=46 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00, +/* sc=47 */ F(49), '7', '7', '7', '7', '7', '7', '7', 0x80, 0x02, +/* sc=48 */ F(50), '8', '8', '8', '8', '8', '8', '8', 0x80, 0x02, +/* sc=49 */ F(51), '9', '9', '9', '9', '9', '9', '9', 0x80, 0x02, +/* sc=4a */ F(52), '/', '/', '/', '/', '/', '/', '/', 0x80, 0x02, +/* sc=4b */ F(53), '4', '4', '4', '4', '4', '4', '4', 0x80, 0x02, +/* sc=4c */ NOP, '5', '5', '5', '5', '5', '5', '5', 0x80, 0x02, +/* sc=4d */ F(55), '6', '6', '6', '6', '6', '6', '6', 0x80, 0x02, +/* sc=4e */ F(56), '+', '+', '+', '+', '+', '+', '+', 0x80, 0x02, +/* sc=4f */ F(57), '1', '1', '1', '1', '1', '1', '1', 0x80, 0x02, +/* sc=50 */ F(58), '2', '2', '2', '2', '2', '2', '2', 0x80, 0x02, +/* sc=51 */ F(59), '3', '3', '3', '3', '3', '3', '3', 0x80, 0x02, +/* sc=52 */ F(60), '0', '0', '0', '0', '0', '0', '0', 0x80, 0x02, +/* sc=53 */ 0x7F, '.', '.', '.', '.', '.', '.', '.', 0x00, 0x02, +/* sc=54 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=56 */ '<', '>', 0x1C, 0x1C, '\\', '>', 0x1C, 0x1C, 0x00, 0x00, +/* sc=57 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00, +/* sc=58 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00, +/* sc=59 */ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x02, +/* sc=5a */ RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, 0xFF, 0x00, +/* sc=5b */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x00, +/* sc=5c */ '*', '*', '*', '*', '*', '*', '*', '*', 0x00, 0x00, +/* sc=5d */ RALT, RALT, RALT, RALT, RALT, RALT, RALT, RALT, 0xFF, 0x00, +/* sc=5e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00, +/* sc=5f */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00, +/* sc=60 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00, +/* sc=61 */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00, +/* sc=62 */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00, +/* sc=63 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00, +/* sc=64 */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00, +/* sc=65 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00, +/* sc=66 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00, +/* sc=67 */ F(54), F(54), F(54), F(54), F(54), F(54), F(54), F(54), 0xFF, 0x00, +/* sc=68 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00, +}; + +#else + +keymap_t key_map = { 107, /* US iso8859 keymap */ +/* alt + * scan cntrl alt alt cntrl + * code base shift cntrl shift alt shift cntrl shift spcl flgs + * --------------------------------------------------------------------------- + */ +/* sc=00 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=01 */ 0x1B, 0x1B, NOP, NOP, 0x1B, 0x1B, NOP, NOP, 0x33, 0x00, +/* sc=02 */ '1', '!', NOP, NOP, '1', '!', NOP, NOP, 0x33, 0x00, +/* sc=03 */ '2', '@', 0x00, 0x00, '2', '@', 0x00, 0x00, 0x00, 0x00, +/* sc=04 */ '3', '#', NOP, NOP, '3', '#', NOP, NOP, 0x33, 0x00, +/* sc=05 */ '4', '$', NOP, NOP, '4', '$', NOP, NOP, 0x33, 0x00, +/* sc=06 */ '5', '%', NOP, NOP, '5', '%', NOP, NOP, 0x33, 0x00, +/* sc=07 */ '6', '^', 0x1E, 0x1E, '6', '^', 0x1E, 0x1E, 0x00, 0x00, +/* sc=08 */ '7', '&', NOP, NOP, '7', '&', NOP, NOP, 0x33, 0x00, +/* sc=09 */ '8', '*', NOP, NOP, '8', '*', NOP, NOP, 0x33, 0x00, +/* sc=0a */ '9', '(', NOP, NOP, '9', '(', NOP, NOP, 0x33, 0x00, +/* sc=0b */ '0', ')', NOP, NOP, '0', ')', NOP, NOP, 0x33, 0x00, +/* sc=0c */ '-', '_', 0x1F, 0x1F, '-', '_', 0x1F, 0x1F, 0x00, 0x00, +/* sc=0d */ '=', '+', NOP, NOP, '=', '+', NOP, NOP, 0x33, 0x00, +/* sc=0e */ 0x08, 0x08, 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00, +/* sc=0f */ 0x09, 0x08, NOP, NOP, 0x09, 0x08, NOP, NOP, 0x33, 0x00, +/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01, +/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01, +/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01, +/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01, +/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01, +/* sc=15 */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01, +/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01, +/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01, +/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01, +/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01, +/* sc=1a */ '[', '{', 0x1B, 0x1B, '[', '{', 0x1B, 0x1B, 0x00, 0x00, +/* sc=1b */ ']', '}', 0x1D, 0x1D, ']', '}', 0x1D, 0x1D, 0x00, 0x00, +/* sc=1c */ 0x0D, 0x0D, 0x0A, 0x0A, 0x0D, 0x0D, 0x0A, 0x0A, 0x00, 0x00, +/* sc=1d */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00, +/* sc=1e */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01, +/* sc=1f */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01, +/* sc=20 */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01, +/* sc=21 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01, +/* sc=22 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01, +/* sc=23 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01, +/* sc=24 */ 'j', 'J', 0x0A, 0x0A, 'j', 'J', 0x0A, 0x0A, 0x00, 0x01, +/* sc=25 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01, +/* sc=26 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01, +/* sc=27 */ ';', ':', NOP, NOP, ';', ':', NOP, NOP, 0x33, 0x00, +/* sc=28 */ '\'', '"', NOP, NOP, '\'', '"', NOP, NOP, 0x33, 0x00, +/* sc=29 */ '`', '~', NOP, NOP, '`', '~', NOP, NOP, 0x33, 0x00, +/* sc=2a */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00, +/* sc=2b */ '\\', '|', 0x1C, 0x1C, '\\', '|', 0x1C, 0x1C, 0x00, 0x00, +/* sc=2c */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01, +/* sc=2d */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01, +/* sc=2e */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01, +/* sc=2f */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01, +/* sc=30 */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01, +/* sc=31 */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01, +/* sc=32 */ 'm', 'M', 0x0D, 0x0D, 'm', 'M', 0x0D, 0x0D, 0x00, 0x01, +/* sc=33 */ ',', '<', NOP, NOP, ',', '<', NOP, NOP, 0x33, 0x00, +/* sc=34 */ '.', '>', NOP, NOP, '.', '>', NOP, NOP, 0x33, 0x00, +/* sc=35 */ '/', '?', NOP, NOP, '/', '?', NOP, NOP, 0x33, 0x00, +/* sc=36 */ RSH, RSH, RSH, RSH, RSH, RSH, RSH, RSH, 0xFF, 0x00, +/* sc=37 */ '*', '*', 0x0A, 0x0A, '*', '*', 0x0A, 0x0A, 0x33, 0x00, +/* sc=38 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00, +/* sc=39 */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 0x00, 0x00, +/* sc=3a */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00, +/* sc=3b */ F( 1), F(13), F(25), F(37), S( 1), S(11), S( 1), S(11), 0xFF, 0x00, +/* sc=3c */ F( 2), F(14), F(26), F(38), S( 2), S(12), S( 2), S(12), 0xFF, 0x00, +/* sc=3d */ F( 3), F(15), F(27), F(39), S( 3), S(13), S( 3), S(13), 0xFF, 0x00, +/* sc=3e */ F( 4), F(16), F(28), F(40), S( 4), S(14), S( 4), S(14), 0xFF, 0x00, +/* sc=3f */ F( 5), F(17), F(29), F(41), S( 5), S(15), S( 5), S(15), 0xFF, 0x00, +/* sc=40 */ F( 6), F(18), F(30), F(42), S( 6), S(16), S( 6), S(16), 0xFF, 0x00, +/* sc=41 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00, +/* sc=42 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00, +/* sc=43 */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00, +/* sc=44 */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00, +/* sc=45 */ NLK, NLK, NLK, NLK, NLK, NLK, NLK, NLK, 0xFF, 0x00, +/* sc=46 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00, +/* sc=47 */ F(49), '7', '7', '7', '7', '7', '7', '7', 0x80, 0x02, +/* sc=48 */ F(50), '8', '8', '8', '8', '8', '8', '8', 0x80, 0x02, +/* sc=49 */ F(51), '9', '9', '9', '9', '9', '9', '9', 0x80, 0x02, +/* sc=4a */ F(52), '-', '-', '-', '-', '-', '-', '-', 0x80, 0x02, +/* sc=4b */ F(53), '4', '4', '4', '4', '4', '4', '4', 0x80, 0x02, +/* sc=4c */ NOP, '5', '5', '5', '5', '5', '5', '5', 0x80, 0x02, +/* sc=4d */ F(55), '6', '6', '6', '6', '6', '6', '6', 0x80, 0x02, +/* sc=4e */ F(56), '+', '+', '+', '+', '+', '+', '+', 0x80, 0x02, +/* sc=4f */ F(57), '1', '1', '1', '1', '1', '1', '1', 0x80, 0x02, +/* sc=50 */ F(58), '2', '2', '2', '2', '2', '2', '2', 0x80, 0x02, +/* sc=51 */ F(59), '3', '3', '3', '3', '3', '3', '3', 0x80, 0x02, +/* sc=52 */ F(60), '0', '0', '0', '0', '0', '0', '0', 0x80, 0x02, +/* sc=53 */ 0x7F, '.', 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00, 0x02, +/* sc=54 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=56 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00, +/* sc=57 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00, +/* sc=58 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00, +/* sc=59 */ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, +/* sc=5a */ RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, 0xFF, 0x00, +/* sc=5b */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x00, +/* sc=5c */ '*', '*', '*', '*', '*', '*', '*', '*', 0x00, 0x00, +/* sc=5d */ RALT, RALT, RALT, RALT, RALT, RALT, RALT, RALT, 0xFF, 0x00, +/* sc=5e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00, +/* sc=5f */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00, +/* sc=60 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00, +/* sc=61 */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00, +/* sc=62 */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00, +/* sc=63 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00, +/* sc=64 */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00, +/* sc=65 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00, +/* sc=66 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00, +/* sc=67 */ F(54), F(54), F(54), F(54), F(54), F(54), F(54), F(54), 0xFF, 0x00, +/* sc=68 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00, +}; + +#endif + +fkeytab_t fkey_tab[60] = { +/* 00-03 */ {"\033[M", 3}, {"\033[N", 3}, {"\033[O", 3}, {"\033[P", 3}, +/* 04-07 */ {"\033[Q", 3}, {"\033[R", 3}, {"\033[S", 3}, {"\033[T", 3}, +/* 08-0B */ {"\033[U", 3}, {"\033[V", 3}, {"\033[W", 3}, {"\033[X", 3}, +/* 0C-0F */ {"\033[W", 3}, {"\033[X", 3}, {"\033[Y", 3}, {"\033[Z", 3}, +/* 10-13 */ {"\033[a", 3}, {"\033[b", 3}, {"\033[c", 3}, {"\033[d", 3}, +/* 14-17 */ {"\033[e", 3}, {"\033[f", 3}, {"\033[g", 3}, {"\033[h", 3}, +/* 18-1B */ {"\033[g", 3}, {"\033[h", 3}, {"\033[i", 3}, {"\033[j", 3}, +/* 1C-1F */ {"\033[k", 3}, {"\033[l", 3}, {"\033[m", 3}, {"\033[n", 3}, +/* 20-23 */ {"\033[o", 3}, {"\033[p", 3}, {"\033[q", 3}, {"\033[r", 3}, +/* 24-27 */ {"\033[g", 3}, {"\033[h", 3}, {"\033[i", 3}, {"\033[j", 3}, +/* 28-2B */ {"\033[k", 3}, {"\033[l", 3}, {"\033[m", 3}, {"\033[n", 3}, +/* 2C-2F */ {"\033[o", 3}, {"\033[p", 3}, {"\033[q", 3}, {"\033[r", 3}, +/* 30-33 */ {"\033[H", 3}, {"\033[A", 3}, {"\033[I", 3}, {"-" , 1}, +/* 34-37 */ {"\033[D", 3}, {"\177" , 1}, {"\033[C", 3}, {"+" , 1}, +/* 38-3B */ {"\033[F", 3}, {"\033[B", 3}, {"\033[G", 3}, {"\033[L", 3} +}; diff --git a/sys/isa/syscons.c b/sys/isa/syscons.c new file mode 100644 index 000000000000..6081c6522bb7 --- /dev/null +++ b/sys/isa/syscons.c @@ -0,0 +1,2128 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz and Don Ahn. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/* + * Heavily modified by Søren Schmidt (sos@kmd-ac.dk) to provide: + * + * virtual consoles, SYSV ioctl's, ANSI emulation + * + * @(#)syscons.c 0.2 930402 + * + * Modified further to provide full (updated) pccons emulation and + * hooks for init_main.c. Jordan Hubbard, 930725 + * + */ + +#include "param.h" +#include "conf.h" +#include "ioctl.h" +#include "proc.h" +#include "user.h" +#include "tty.h" +#include "uio.h" +#include "callout.h" +#include "systm.h" +#include "kernel.h" +#include "syslog.h" +#include "errno.h" +#include "console.h" +#include "malloc.h" +#include "i386/isa/icu.h" +#include "i386/isa/isa.h" +#include "i386/isa/isa_device.h" +#include "i386/include/pc/display.h" +#include "i386/i386/cons.h" +#include "machine/psl.h" +#include "machine/frame.h" +#include "sc.h" +#include "ddb.h" +#include "iso8859.font" +#include "kbdtables.h" +/*#include "asm.h"*/ + +#if NSC > 0 +#ifndef NCONS +#define NCONS 12 +#endif + +/* status flags */ +#define LOCK_KEY_MASK 0x00007 +#define UNKNOWN_MODE 0x00010 +#define KBD_RAW_MODE 0x00020 +#define SWITCH_WAIT_REL 0x00040 +#define SWITCH_WAIT_ACQ 0x00080 + +/* virtual video memory addresses */ +#define MONO_BUF 0xFE0B0000 +#define CGA_BUF 0xFE0B8000 +#define VGA_BUF 0xFE0A0000 +#define VIDEOMEM 0x000A0000 + +/* misc defines */ +#define MAX_ESC_PAR 2 +#define TEXT80x25 1 +#define TEXT80x50 2 +#define COL 80 +#define ROW 25 +#ifndef XTALSPEED +#define XTALSPEED 1193182 /* should be in isa.h */ +#endif + +/* defines related to hardware addresses */ +#define MONO_BASE 0x3B4 /* crt controller base mono */ +#define COLOR_BASE 0x3D4 /* crt controller base color */ +#define ATC 0x3C0 /* attribute controller */ +#define TSIDX 0x3C4 /* timing sequencer idx */ +#define TSREG 0x3C5 /* timing sequencer data */ +#define PIXMASK 0x3C6 /* pixel write mask */ +#define PALRADR 0x3C7 /* palette read address */ +#define PALWADR 0x3C8 /* palette write address */ +#define PALDATA 0x3C9 /* palette data register */ +#define GDCIDX 0x3CE /* graph data controller idx */ +#define GDCREG 0x3CF /* graph data controller data */ + +typedef struct scr_stat { + u_short *crt_base; /* address of screen memory */ + u_short *scr; /* buffer when off screen */ + u_short *crtat; /* cursor address */ + int esc; /* processing escape sequence */ + int n_par; /* # of parameters to ESC */ + int last_par; /* last parameter # */ + int par[MAX_ESC_PAR]; /* contains ESC parameters */ + int posx; /* current X position */ + int posy; /* current Y position */ + int max_posx; /* X size */ + int max_posy; /* X size */ + int attr; /* current attributes */ + int std_attr; /* normal attributes */ + int rev_attr; /* reverse attributes */ + u_char border; /* border color */ + u_short bell_duration; + u_short bell_pitch; + u_short status; /* status (bitfield) */ + u_short mode; /* mode */ + pid_t pid; /* pid of controlling proc */ + struct proc *proc; /* proc* of controlling proc */ + struct vt_mode smode; /* switch mode */ + } scr_stat; + +static scr_stat cons_scr_stat[NCONS]; +static scr_stat *cur_scr_stat = &cons_scr_stat[0]; +static scr_stat *new_scp, *old_scp; +static int switch_in_progress = 0; + +u_short *Crtat = (u_short *)MONO_BUF; +static u_short *crtat = 0; +static u_int crtc_addr = MONO_BASE; +static u_char shfts = 0, ctls = 0, alts = 0; +static char palette[3*256]; +static const u_int n_fkey_tab = sizeof(fkey_tab) / sizeof(*fkey_tab); +static int cur_cursor_pos = -1; +static char in_putc, nx_scr; +static char saved_console = -1; /* saved console number */ +static long blank_time = 0; /* screen saver timout value */ +static scrmap_t scr_map; + +struct tty pccons[NCONS]; +struct tty *cur_pccons = &pccons[0]; +struct tty *new_pccons; + +extern int hz; +extern struct timeval time; + +#define CSF_ACTIVE 0x1 /* timeout active */ +#define CSF_POLLING 0x2 /* polling for input */ + +struct pcconsoftc { + char cs_flags; + char cs_lastc; /* last char sent */ + int cs_timo; /* timeouts since interrupt */ + u_long cs_wedgecnt; /* times restarted */ + } pcconsoftc = {0, 0, 0, 0}; + + +/* special characters */ +#define bs 8 +#define lf 10 +#define cr 13 +#define cntlc 3 +#define del 0177 +#define cntld 4 + +/* function prototypes */ +int pcprobe(struct isa_device *dev); +int pcattach(struct isa_device *dev); +int pcopen(dev_t dev, int flag, int mode, struct proc *p); +int pcclose(dev_t dev, int flag, int mode, struct proc *p); +int pcread(dev_t dev, struct uio *uio, int flag); +int pcwrite(dev_t dev, struct uio *uio, int flag); +int pcparam(struct tty *tp, struct termios *t); +int pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p); +int pcxint(dev_t dev); +int pcstart(struct tty *tp); +int pccnprobe(struct consdev *cp); +int pccninit(struct consdev *cp); +int pccnputc(dev_t dev, char c); +int pccngetc(dev_t dev); +int scintr(dev_t dev, int irq, int cpl); +void scrn_saver(int test); +static struct tty *get_pccons(dev_t dev); +static scr_stat *get_scr_stat(dev_t dev); +static int get_scr_num(scr_stat *scp); +static void cursor_shape(int start, int end); +static void cursor_pos(void); +static void clear_screen(scr_stat *scp); +static switch_scr(u_int next_scr); +static void exchange_scr(void); +static void move_crsr(scr_stat *scp, u_int x, u_int y); +static void move_up(u_short *s, u_short *d, u_int len); +static void move_down(u_short *s, u_short *d, u_int len); +static void scan_esc(scr_stat *scp, u_char c); +static void ansi_put(scr_stat *scp, u_char c); +void consinit(void); +static void sput(u_char c, u_char ca); +static u_char *get_fstr(u_int c, u_int *len); +static update_leds(int which); +void reset_cpu(void); +u_int sgetc(int noblock); +int pcmmap(dev_t dev, int offset, int nprot); +int getchar(void); +static void kbd_wait(void); +static void kbd_cmd(u_char command); +static void set_mode(scr_stat *scp); +static void set_border(int color); +static load_font(int segment, int size, char* font); +static void save_palette(void); +static void load_palette(void); +static change_winsize(struct tty *tp, int x, int y); + +struct isa_driver scdriver = { + pcprobe, pcattach, "sc", + }; + + +int pcprobe(struct isa_device *dev) +{ + u_char c; + int i, again = 0; + + /* Enable interrupts and keyboard controller */ + kbd_wait(); + outb(KB_STAT, KB_WRITE); + kbd_cmd(0x4D); + + /* Start keyboard stuff RESET */ + kbd_cmd(KB_RESET); + while ((c=inb(KB_DATA)) != KB_ACK) { + if ((c == 0xFE) || (c == 0xFF)) { + if (!again) + printf("KEYBOARD disconnected: RECONNECT \n"); + kbd_cmd(KB_RESET); + again = 1; + } + } + /* + * pick up keyboard reset return code SOS + * some keyboards / controllers hangs if this is enabled + */ + /* while ((c=inb(KB_DATA))!=0xAA); */ + return 1; +} + + +int pcattach(struct isa_device *dev) +{ + scr_stat *scp; + int i; + + if (crtc_addr == MONO_BASE) + printf("VGA mono"); + else + printf("VGA color"); + + if (NCONS > 1) + printf(" <%d virtual consoles>\n", NCONS); + else + printf("\n"); + save_palette(); + load_font(0, 16, font_8x16); + load_font(1, 8, font_8x8); + for (i = 0; i < NCONS; i++) { + scp = &cons_scr_stat[i]; + scp->mode = TEXT80x25; + scp->scr = (u_short *)malloc(COL * ROW * 2, M_DEVBUF, M_NOWAIT); + scp->std_attr = (FG_LIGHTGREY | BG_BLACK) << 8; + scp->rev_attr = (FG_BLACK | BG_LIGHTGREY) << 8; + scp->attr = scp->std_attr; + scp->border = BG_BLACK; + scp->esc = 0; + scp->max_posx = COL; + scp->max_posy = ROW; + scp->bell_pitch = 800; + scp->bell_duration = 10; + scp->status = 0; + scp->pid = 0; + scp->proc = NULL; + scp->smode.mode = VT_AUTO; + if (i > 0) { + scp->crt_base = scp->crtat = scp->scr; + fillw(scp->attr | ' ', scp->scr, COL * ROW); + } + } + cursor_pos(); +} + + +static struct tty *get_pccons(dev_t dev) +{ + int i = minor(dev); + + if (i >= NCONS) + return(NULL); + return(&pccons[i]); +} + + +static scr_stat *get_scr_stat(dev_t dev) +{ + int i = minor(dev); + + if (i >= NCONS) + return(NULL); + return(&cons_scr_stat[i]); +} + + +static int get_scr_num(scr_stat *scp) /* allways call with legal scp !! */ +{ + int i = 0; + + while ((i < NCONS) && (cur_scr_stat != &cons_scr_stat[i])) i++; + return i; +} + +pcopen(dev_t dev, int flag, int mode, struct proc *p) +{ + struct tty *tp = get_pccons(dev); + + if (!tp) + return(ENXIO); + tp->t_oproc = pcstart; + tp->t_param = pcparam; + tp->t_dev = dev; + if ((tp->t_state & TS_ISOPEN) == 0) { + tp->t_state |= TS_WOPEN; + ttychars(tp); + tp->t_iflag = TTYDEF_IFLAG; + tp->t_oflag = TTYDEF_OFLAG; + tp->t_cflag = TTYDEF_CFLAG; + tp->t_lflag = TTYDEF_LFLAG; + tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; + pcparam(tp, &tp->t_termios); + ttsetwater(tp); + } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) + return(EBUSY); + tp->t_state |= TS_CARR_ON; + return((*linesw[tp->t_line].l_open)(dev, tp)); +} + + +pcclose(dev_t dev, int flag, int mode, struct proc *p) +{ + struct tty *tp = get_pccons(dev); + struct scr_stat *scp; + + if (!tp) + return(ENXIO); + scp = get_scr_stat(tp->t_dev); + scp->pid = 0; + scp->proc = NULL; + scp->smode.mode = VT_AUTO; + (*linesw[tp->t_line].l_close)(tp, flag); + ttyclose(tp); + return(0); +} + + +pcread(dev_t dev, struct uio *uio, int flag) +{ + struct tty *tp = get_pccons(dev); + + if (!tp) + return(ENXIO); + return((*linesw[tp->t_line].l_read)(tp, uio, flag)); +} + + +pcwrite(dev_t dev, struct uio *uio, int flag) +{ + struct tty *tp = get_pccons(dev); + + if (!tp) + return(ENXIO); + return((*linesw[tp->t_line].l_write)(tp, uio, flag)); +} + + +/* + * Got a console interrupt, keyboard action ! + * Catch the character, and see who it goes to. + */ +scintr(dev_t dev, int irq, int cpl) +{ + int c, len; + u_char *cp; + + scrn_saver(0); + c = sgetc(1); + if (c & 0x100) + return; + if (pcconsoftc.cs_flags & CSF_POLLING) + return; + if (c < 0x100) + (*linesw[cur_pccons->t_line].l_rint)(c & 0xFF, cur_pccons); + else if (cp = get_fstr((u_int)c, (u_int *)&len)) { + while (len-- > 0) + (*linesw[cur_pccons->t_line].l_rint) + (*cp++ & 0xFF, cur_pccons); + } +} + + +/* + * Set line parameters + */ +pcparam(struct tty *tp, struct termios *t) +{ + int cflag = t->c_cflag; + + /* and copy to tty */ + tp->t_ispeed = t->c_ispeed; + tp->t_ospeed = t->c_ospeed; + tp->t_cflag = cflag; + return(0); +} + + +pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) +{ + int i, error; + struct tty *tp; + struct syscframe *fp; + scr_stat *scp; + + tp = get_pccons(dev); + if (!tp) + return(ENXIO); + scp = get_scr_stat(tp->t_dev); + + switch (cmd) { /* process console hardware related ioctl's */ + + case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */ + blank_time = *(int*)data; + return 0; + + case CONS_80x25TEXT: /* set 80x25 text mode */ + scp->mode = TEXT80x25; + scp->max_posy = 25; + set_mode(scp); + clear_screen(scp); + change_winsize(tp, scp->max_posx, scp->max_posy); + free(scp->scr, M_DEVBUF); + scp->scr = (u_short *)malloc(scp->max_posx*scp->max_posy*2, + M_DEVBUF, M_NOWAIT); + return 0; + + case CONS_80x50TEXT: /* set 80x50 text mode */ + scp->mode = TEXT80x50; + scp->max_posy = 50; + set_mode(scp); + clear_screen(scp); + change_winsize(tp, scp->max_posx, scp->max_posy); + free(scp->scr, M_DEVBUF); + scp->scr = (u_short *)malloc(scp->max_posx*scp->max_posy*2, + M_DEVBUF, M_NOWAIT); + return 0; + + case CONS_GETINFO: /* get current (virtual) console info */ + if (*data == sizeof(struct vid_info)) { + vid_info_t *ptr = (vid_info_t*)data; + ptr->m_num = get_scr_num(scp); + ptr->mv_col = scp->posx; + ptr->mv_row = scp->posy; + ptr->mv_csz = scp->max_posx; + ptr->mv_rsz = scp->max_posy; + ptr->mv_norm.fore = (scp->std_attr & 0x0f00)>>8; + ptr->mv_norm.back = (scp->std_attr & 0xf000)>>12; + ptr->mv_rev.fore = (scp->rev_attr & 0x0f00)>>8; + ptr->mv_rev.back = (scp->rev_attr & 0xf000)>>12; + ptr->mv_grfc.fore = 0; /* not supported */ + ptr->mv_grfc.back = 0; /* not supported */ + ptr->mv_ovscan = scp->border; + ptr->mk_keylock = scp->status & LOCK_KEY_MASK; + return 0; + } + return EINVAL; + + case VT_SETMODE: /* set screen switcher mode */ + bcopy(data, &scp->smode, sizeof(struct vt_mode)); + if (scp->smode.mode == VT_PROCESS) { + scp->proc = p; + scp->pid = scp->proc->p_pid; + } + return 0; + + case VT_GETMODE: /* get screen switcher mode */ + bcopy(&scp->smode, data, sizeof(struct vt_mode)); + return 0; + + case VT_RELDISP: /* screen switcher ioctl */ + switch(*data) { + case VT_FALSE: /* user refuses to release screen, abort */ + if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) { + old_scp->status &= ~SWITCH_WAIT_REL; + switch_in_progress = 0; + return 0; + } + return EINVAL; + + case VT_TRUE: /* user has released screen, go on */ + if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) { + scp->status &= ~SWITCH_WAIT_REL; + exchange_scr(); + if (new_scp->smode.mode == VT_PROCESS) { + new_scp->status |= SWITCH_WAIT_ACQ; + psignal(new_scp->proc, + new_scp->smode.acqsig); + } + else + switch_in_progress = 0; + return 0; + } + return EINVAL; + + case VT_ACKACQ: /* acquire acknowledged, switch completed */ + if (scp == new_scp && (scp->status & SWITCH_WAIT_ACQ)) { + scp->status &= ~SWITCH_WAIT_ACQ; + switch_in_progress = 0; + return 0; + } + return EINVAL; + + default: + return EINVAL; + } + /* NOT REACHED */ + + case VT_OPENQRY: /* return free virtual cons, allways current */ + *data = get_scr_num(scp); + return 0; + + case VT_ACTIVATE: /* switch to screen *data */ + return switch_scr((*data) - 1); + + case VT_WAITACTIVE: /* wait for switch to occur */ + if (*data > NCONS) + return EINVAL; + if (minor(dev) == (*data) - 1) + return 0; + if (*data == 0) { + if (scp == cur_scr_stat) + return 0; + while ((error=tsleep(&scp->smode, + PZERO|PCATCH, "waitvt", 0)) + == ERESTART) ; + } + else + while ((error=tsleep(&cons_scr_stat[*data].smode, + PZERO|PCATCH, "waitvt", 0)) + == ERESTART) ; + return error; + + case KDENABIO: /* allow io operations */ + fp = (struct syscframe *)p->p_regs; + fp->sf_eflags |= PSL_IOPL; + return 0; + + case KDDISABIO: /* disallow io operations (default) */ + fp = (struct syscframe *)p->p_regs; + fp->sf_eflags &= ~PSL_IOPL; + return 0; + + case KDSETMODE: /* set current mode of this (virtual) console */ + switch (*data) { + case KD_TEXT: /* switch to TEXT (known) mode */ + /* restore fonts & palette ! */ + load_font(0, 16, font_8x16); + load_font(1, 8, font_8x8); + load_palette(); + /* FALL THROUGH */ + + case KD_TEXT1: /* switch to TEXT (known) mode */ + /* no restore fonts & palette */ + scp->status &= ~UNKNOWN_MODE; + set_mode(scp); + clear_screen(scp); + return 0; + + case KD_GRAPHICS:/* switch to GRAPHICS (unknown) mode */ + scp->status |= UNKNOWN_MODE; + return 0; + default: + return EINVAL; + } + /* NOT REACHED */ + + case KDGETMODE: /* get current mode of this (virtual) console */ + *data = (scp->status & UNKNOWN_MODE) ? KD_GRAPHICS : KD_TEXT; + return 0; + + case KDSBORDER: /* set border color of this (virtual) console */ + scp->border = *data; + if (scp == cur_scr_stat) + set_border(scp->border); + return 0; + + case KDSKBSTATE: /* set keyboard state (locks) */ + if (*data >= 0 && *data < 4) { + scp->status &= ~LOCK_KEY_MASK; + scp->status |= *data; + if (scp == cur_scr_stat) + update_leds(scp->status & LOCK_KEY_MASK); + return 0; + } + return EINVAL; + + case KDGKBSTATE: /* get keyboard state (locks) */ + *data = scp->status & LOCK_KEY_MASK; + return 0; + + case KDSETRAD: /* set keyboard repeat & delay rates */ + if (*(u_char*)data < 0x80) { + kbd_cmd(KB_SETRAD); + kbd_cmd(*data & 0x7f); + return 0; + } + return EINVAL; + + case KDSKBMODE: /* set keyboard mode */ + switch (*data) { + case K_RAW: /* switch to RAW scancode mode */ + scp->status |= KBD_RAW_MODE; + return 0; + + case K_XLATE: /* switch to XLT ascii mode */ + scp->status &= ~KBD_RAW_MODE; + return 0; + default: + return EINVAL; + } + /* NOT REACHED */ + + case KDGKBMODE: /* get keyboard mode */ + *data = (scp->status & KBD_RAW_MODE) ? K_RAW : K_XLATE; + return 0; + + case KDMKTONE: /* sound the bell */ + if (scp == cur_scr_stat) + sysbeep(scp->bell_pitch, scp->bell_duration); + return 0; + + case KIOCSOUND: /* make tone (*data) hz */ + if (scp == cur_scr_stat) { + if (*(int*)data) { + int pitch = XTALSPEED/(*(int*)data); + /* enable counter 2 */ + outb(0x61, inb(0x61) | 3); + /* set command for counter 2, 2 byte write */ + outb(0x43, 0xb6); + /* set pitch */ + outb(0x42, pitch); + outb(0x42, (pitch>>8)); + } + else { + /* disable counter 2 */ + outb(0x61, inb(0x61) & 0xFC); + } + } + return 0; + + case KDGKBTYPE: /* get keyboard type */ + *data = 0; /* type not known (yet) */ + return 0; + + case KDSETLED: /* set keyboard LED status */ + scp->status &= ~LOCK_KEY_MASK; + scp->status |= (*data & LOCK_KEY_MASK); + if (scp == cur_scr_stat) + update_leds(scp->status & LOCK_KEY_MASK); + return 0; + + case KDGETLED: /* get keyboard LED status */ + *data = scp->status & LOCK_KEY_MASK; + return 0; + + case GETFKEY: /* get functionkey string */ + if (*(u_short*)data < n_fkey_tab) { + fkeyarg_t *ptr = (fkeyarg_t*)data; + bcopy(&fkey_tab[ptr->keynum].str, + ptr->keydef, + fkey_tab[ptr->keynum].len); + ptr->flen = fkey_tab[ptr->keynum].len; + return 0; + } + else + return EINVAL; + + case SETFKEY: /* set functionkey string */ + if (*(u_short*)data < n_fkey_tab) { + fkeyarg_t *ptr = (fkeyarg_t*)data; + bcopy(ptr->keydef, + &fkey_tab[ptr->keynum].str, + min(ptr->flen, MAXFK)); + fkey_tab[ptr->keynum].len = min(ptr->flen, MAXFK); + return 0; + } + else + return EINVAL; + + case GIO_SCRNMAP: /* get output translation table */ + bcopy(&scr_map, data, sizeof(scrmap_t)); + return 0; + + case PIO_SCRNMAP: /* set output translation table */ + bcopy(data, &scr_map, sizeof(scrmap_t)); + return 0; + + case GIO_KEYMAP: /* get keyboard translation table */ + bcopy(&key_map, data, sizeof(key_map)); + return 0; + + case PIO_KEYMAP: /* set keyboard translation table */ + bcopy(data, &key_map, sizeof(key_map)); + return 0; + + case PIO_FONT8x8: /* set 8x8 dot font */ + bcopy(data, &font_8x8, sizeof(fnt8_t)); + load_font(1, 8, font_8x16); + return 0; + + case GIO_FONT8x8: /* get 8x8 dot font */ + bcopy(&font_8x8, data, sizeof(fnt8_t)); + return 0; + + case PIO_FONT8x14: /* set 8x14 dot font */ + bcopy(data, &font_8x14, sizeof(fnt14_t)); + load_font(2, 14, font_8x14); + return 0; + + case GIO_FONT8x14: /* get 8x14 dot font */ + bcopy(&font_8x14, data, sizeof(fnt14_t)); + return 0; + + case PIO_FONT8x16: /* set 8x16 dot font */ + bcopy(data, &font_8x16, sizeof(fnt16_t)); + load_font(0, 16, font_8x16); + return 0; + + case GIO_FONT8x16: /* get 8x16 dot font */ + bcopy(&font_8x16, data, sizeof(fnt16_t)); + return 0; + + case CONSOLE_X_MODE_ON: /* just to be compatible */ + if (saved_console < 0) { + saved_console = get_scr_num(cur_scr_stat); + switch_scr(minor(dev)); + fp = (struct syscframe *)p->p_regs; + fp->sf_eflags |= PSL_IOPL; + scp->status |= UNKNOWN_MODE; + scp->status |= KBD_RAW_MODE; + return 0; + } + return EAGAIN; + + case CONSOLE_X_MODE_OFF:/* just to be compatible */ + fp = (struct syscframe *)p->p_regs; + fp->sf_eflags &= ~PSL_IOPL; + load_font(0, 16, font_8x16); + load_font(1, 8, font_8x8); + scp->status &= ~UNKNOWN_MODE; + set_mode(scp); + clear_screen(scp); + scp->status &= ~KBD_RAW_MODE; + switch_scr(saved_console); + saved_console = -1; + return 0; + + case CONSOLE_X_BELL: + /* + * if set, data is a pointer to a length 2 array of + * integers. data[0] is the pitch in Hz and data[1] + * is the duration in msec. + */ + if (data) + sysbeep(1187500/ ((int*)data)[0], + ((int*)data)[1] * hz/ 3000); + else + sysbeep(0x31b, hz/4); + return 0; + + default: + break; + } + + error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); + if (error >= 0) + return(error); + error = ttioctl(tp, cmd, data, flag); + if (error >= 0) + return(error); + return(ENOTTY); +} + + +pcxint(dev_t dev) +{ + pccons[minor(dev)].t_state &= ~TS_BUSY; + pcconsoftc.cs_timo = 0; + if (pccons[minor(dev)].t_line) + (*linesw[pccons[minor(dev)].t_line].l_start) + (&pccons[minor(dev)]); + else + pcstart(&pccons[minor(dev)]); +} + + +pcstart(struct tty *tp) +{ + int c, s; + scr_stat *scp = get_scr_stat(tp->t_dev); + + s = spltty(); + if (!(tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))) + for (;;) { + if (RB_LEN(&tp->t_out) <= tp->t_lowat) { + if (tp->t_state & TS_ASLEEP) { + tp->t_state &= ~TS_ASLEEP; + wakeup((caddr_t)&tp->t_out); + } + if (tp->t_wsel) { + selwakeup(tp->t_wsel, + tp->t_state & TS_WCOLL); + tp->t_wsel = 0; + tp->t_state &= ~TS_WCOLL; + } + } + if (RB_LEN(&tp->t_out) == 0) + break; + if (scp->status & SLKED) + break; + c = getc(&tp->t_out); + splx(s); + ansi_put(scp, c); + s = spltty(); + } + splx(s); +} + + +pccnprobe(struct consdev *cp) +{ + int maj; + + /* locate the major number */ + for (maj = 0; maj < nchrdev; maj++) + if (cdevsw[maj].d_open == pcopen) + break; + + /* initialize required fields */ + cp->cn_dev = makedev(maj, 0); + cp->cn_tp = &pccons[0]; + cp->cn_pri = CN_INTERNAL; +} + + +pccninit(struct consdev *cp) +{ +} + + +pccnputc(dev_t dev, char c) +{ + int pos; + + if (cur_scr_stat->status & UNKNOWN_MODE) + return; + if (c == '\n') + sput('\r', FG_LIGHTGREY | BG_BLACK); + sput(c, FG_LIGHTGREY | BG_BLACK); + pos = cur_scr_stat->crtat - cur_scr_stat->crt_base; + if (pos != cur_cursor_pos) { + cur_cursor_pos = pos; + outb(crtc_addr,14); + outb(crtc_addr+1,pos >> 8); + outb(crtc_addr,15); + outb(crtc_addr+1,pos&0xff); + } +} + + +pccngetc(dev_t dev) +{ + int c, s; + + s = spltty(); /* block scintr while we poll */ + c = sgetc(0); + splx(s); + if (c == '\r') c = '\n'; + return(c); +} + +#ifndef DONT_BLANK + +void scrn_saver(int test) +{ + u_char val; + static int blanked = 0; + static long time_stamp; + + if (test && blank_time) { + if (time.tv_sec > time_stamp + blank_time) { + blanked = 1; + outb(TSIDX, 0x01); val = inb(TSREG); + outb(TSIDX, 0x01); outb(TSREG, val | 0x20); + } + } + else { + time_stamp = time.tv_sec; + if (blanked) { + blanked = 0; + outb(TSIDX, 0x01); val = inb(TSREG); + outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); + } + } +} + +#else +/* + * alternative screen saver for cards that do not like blanking + * donated by Christoph Robitchko + */ +static u_short cur_cursor_shape; /* remember cursor shape */ + +void scrn_saver(int test) +{ + const char saves[] = {"386BSD"}; + static int blanked = 0; + static u_char *savs[sizeof(saves)-1]; + static int dirx, diry; + static long time_stamp; + static u_short save_cursor; + int f; + scr_stat *scp = cur_scr_stat; + + if (test && blank_time) { + if (time.tv_sec > time_stamp + blank_time) { + if (!blanked) { + bcopy(Crtat, scp->scr, + scp->max_posx * scp->max_posy * 2); + fillw(0x07<<8 | ' ', Crtat, + scp->max_posx * scp->max_posy); + set_border(0); + dirx = (scp->posx ? 1 : -1); + diry = (scp->posy ? + scp->max_posx : -scp->max_posx); + for (f=0; f< sizeof(saves)-1; f++) + savs[f] = (u_char *)Crtat + 2 * + (scp->posx+scp->posy*scp->max_posx); + *(savs[0]) = *saves; + f = scp->max_posy * scp->max_posx + 5; + outb(crtc_addr, 14); + outb(crtc_addr+1, f >> 8); + outb(crtc_addr, 15); + outb(crtc_addr+1, f & 0xff); + save_cursor = cur_cursor_shape; + blanked = 1; + } + if (blanked++ < 4) + return; + blanked = 1; + *(savs[sizeof(saves)-2]) = ' '; + for (f=sizeof(saves)-2; f > 0; f--) + savs[f] = savs[f-1]; + f = (savs[0] - (u_char *)Crtat) / 2; + if ((f % scp->max_posx) == 0 || + (f % scp->max_posx) == scp->max_posx - 1) + dirx = -dirx; + if ((f / scp->max_posx) == 0 || + (f / scp->max_posx) == scp->max_posy - 1) + diry = -diry; + savs[0] += 2*dirx + 2*diry; + for (f=sizeof(saves)-2; f>=0; f--) + *(savs[f]) = saves[f]; + } + } + else { + time_stamp = time.tv_sec; + if (blanked) { + bcopy(scp->scr, Crtat, + scp->max_posx * scp->max_posy * 2); + cur_cursor_pos = -1; + cursor_shape((save_cursor >> 8) & 0xff, + save_cursor & 0xff); + set_border(scp->border); + blanked = 0; + } + } +} + +#endif /* DONT_BLANK */ + +static void cursor_shape(int start, int end) +{ + outb(crtc_addr, 10); + outb(crtc_addr+1, start & 0xFF); + outb(crtc_addr, 11); + outb(crtc_addr+1, end & 0xFF); +#ifdef DONT_BLANK + cur_cursor_shape = ((start & 0xff) << 8) | (end & 0xff); +#endif +} + + +static void cursor_pos(void) +{ + int pos = cur_scr_stat->crtat - cur_scr_stat->crt_base; + + if (cur_scr_stat->status & UNKNOWN_MODE) + return; + scrn_saver(1); + if (pos != cur_cursor_pos) { + cur_cursor_pos = pos; + outb(crtc_addr,14); + outb(crtc_addr+1,pos >> 8); + outb(crtc_addr,15); + outb(crtc_addr+1,pos&0xff); + } + timeout(cursor_pos,0,hz/20); +} + + +static void clear_screen(scr_stat *scp) +{ + move_crsr(scp, 0, 0); + fillw(scp->attr | ' ', scp->crt_base, + scp->max_posx * scp->max_posy); +} + + +static switch_scr(u_int next_scr) +{ + if (in_putc) { /* don't switch if in putc */ + nx_scr = next_scr + 1; + return 0; + } + if (next_scr >= NCONS || switch_in_progress) { + sysbeep(800, hz/4); + return -1; + } + switch_in_progress = 1; + old_scp = cur_scr_stat; + new_scp = &cons_scr_stat[next_scr]; + wakeup(&new_scp->smode); + if (new_scp == old_scp) { + switch_in_progress = 0; + return 0; + } + new_pccons = &pccons[next_scr]; + + /* has controlling process died? */ + if (old_scp->proc && (old_scp->proc != pfind(old_scp->pid))) + old_scp->smode.mode = VT_AUTO; + if (new_scp->proc && (new_scp->proc != pfind(new_scp->pid))) + new_scp->smode.mode = VT_AUTO; + + /* check the modes and switch approbiatly */ + if (old_scp->smode.mode == VT_PROCESS) { + old_scp->status |= SWITCH_WAIT_REL; + psignal(old_scp->proc, old_scp->smode.relsig); + } + else { + exchange_scr(); + if (new_scp->smode.mode == VT_PROCESS) { + new_scp->status |= SWITCH_WAIT_ACQ; + psignal(new_scp->proc, new_scp->smode.acqsig); + } + else + switch_in_progress = 0; + } + return 0; +} + + +static void exchange_scr(void) +{ + bcopy(Crtat, old_scp->scr, old_scp->max_posx * old_scp->max_posy * 2); + old_scp->crt_base = old_scp->scr; + move_crsr(old_scp, old_scp->posx, old_scp->posy); + cur_scr_stat = new_scp; + cur_pccons = new_pccons; + if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE) + shfts = ctls = alts = 0; + update_leds(new_scp->status & LOCK_KEY_MASK); + set_mode(new_scp); + new_scp->crt_base = Crtat; + move_crsr(new_scp, new_scp->posx, new_scp->posy); + bcopy(new_scp->scr, Crtat, new_scp->max_posx * new_scp->max_posy * 2); + nx_scr = 0; +} + + +static void move_crsr(scr_stat *scp, u_int x, u_int y) +{ + if (x < 0 || y < 0 || x >= scp->max_posx || y >= scp->max_posy) + return; + scp->posx = x; + scp->posy = y; + scp->crtat = scp->crt_base + scp->posy * scp->max_posx + scp->posx; +} + + +static void move_up(u_short *s, u_short *d, u_int len) +{ + s += len; + d += len; + while (len-- > 0) + *--d = *--s; +} + + +static void move_down(u_short *s, u_short *d, u_int len) +{ + while (len-- > 0) + *d++ = *s++; +} + + +static void scan_esc(scr_stat *scp, u_char c) +{ + static u_char ansi_col[16] = + {0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15}; + int i, n, m; + u_short *src, *dst, count; + + if (scp->esc == 1) { + switch (c) { + + case '[': /* Start ESC [ sequence */ + scp->esc = 2; + scp->last_par = -1; + for (i = scp->n_par; i < MAX_ESC_PAR; i++) + scp->par[i] = 1; + scp->n_par = 0; + return; + + case 'M': /* Move cursor up 1 line, scroll if at top */ + if (scp->posy > 0) + move_crsr(scp, scp->posx, scp->posy - 1); + else { + move_up(scp->crt_base, + scp->crt_base + scp->max_posx, + (scp->max_posy - 1) * scp->max_posx); + fillw(scp->attr | ' ', + scp->crt_base, scp->max_posx); + } + break; +#if notyet + case 'Q': + scp->esc = 4; + break; +#endif + case 'c': /* Clear screen & home */ + clear_screen(scp); + break; + } + } + else if (scp->esc == 2) { + if (c >= '0' && c <= '9') { + if (scp->n_par < MAX_ESC_PAR) { + if (scp->last_par != scp->n_par) { + scp->last_par = scp->n_par; + scp->par[scp->n_par] = 0; + } + else + scp->par[scp->n_par] *= 10; + scp->par[scp->n_par] += c - '0'; + return; + } + } + scp->n_par = scp->last_par + 1; + switch (c) { + + case ';': + if (scp->n_par < MAX_ESC_PAR) + return; + break; + + case '=': + scp->esc = 3; + scp->last_par = -1; + for (i = scp->n_par; i < MAX_ESC_PAR; i++) + scp->par[i] = 1; + scp->n_par = 0; + return; + + case 'A': /* up n rows */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx, scp->posy - n); + break; + + case 'B': /* down n rows */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx, scp->posy + n); + break; + + case 'C': /* right n columns */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx + n, scp->posy); + break; + + case 'D': /* left n columns */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx - n, scp->posy); + break; + + case 'E': /* cursor to start of line n lines down */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, 0, scp->posy + n); + break; + + case 'F': /* cursor to start of line n lines up */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, 0, scp->posy - n); + break; + + case 'f': /* System V consoles .. */ + case 'H': /* Cursor move */ + if (scp->n_par == 0) + move_crsr(scp, 0, 0); + else if (scp->n_par == 2) + move_crsr(scp, scp->par[1] - 1, scp->par[0] - 1); + break; + + case 'J': /* Clear all or part of display */ + if (scp->n_par == 0) + n = 0; + else + n = scp->par[0]; + switch (n) { + case 0: /* clear form cursor to end of display */ + fillw(scp->attr | ' ', scp->crtat, + scp->crt_base + scp->max_posx * + scp->max_posy - scp->crtat); + break; + case 1: /* clear from beginning of display to cursor */ + fillw(scp->attr | ' ', scp->crt_base, + scp->crtat - scp->crt_base); + break; + case 2: /* clear entire display */ + clear_screen(scp); + break; + } + break; + + case 'K': /* Clear all or part of line */ + if (scp->n_par == 0) + n = 0; + else + n = scp->par[0]; + switch (n) { + case 0: /* clear form cursor to end of line */ + fillw(scp->attr | ' ', scp->crtat, + scp->max_posx - scp->posx); + break; + case 1: /* clear from beginning of line to cursor */ + fillw(scp->attr | ' ', + scp->crtat - (scp->max_posx - scp->posx), + (scp->max_posx - scp->posx) + 1); + break; + case 2: /* clear entire line */ + fillw(scp->attr | ' ', + scp->crtat - (scp->max_posx - scp->posx), + scp->max_posx); + break; + } + break; + + case 'L': /* Insert n lines */ + n = scp->par[0]; if (n < 1) n = 1; + if (n > scp->max_posy - scp->posy) + n = scp->max_posy - scp->posy; + src = scp->crt_base + scp->posy * scp->max_posx; + dst = src + n * scp->max_posx; + count = scp->max_posy - (scp->posy + n); + move_up(src, dst, count * scp->max_posx); + fillw(scp->attr | ' ', src, n * scp->max_posx); + break; + + case 'M': /* Delete n lines */ + n = scp->par[0]; if (n < 1) n = 1; + if (n > scp->max_posy - scp->posy) + n = scp->max_posy - scp->posy; + dst = scp->crt_base + scp->posy * scp->max_posx; + src = dst + n * scp->max_posx; + count = scp->max_posy - (scp->posy + n); + move_down(src, dst, count * scp->max_posx); + src = dst + count * scp->max_posx; + fillw(scp->attr | ' ', src, n * scp->max_posx); + break; + + case 'P': /* Delete n chars */ + n = scp->par[0]; if (n < 1) n = 1; + if (n > scp->max_posx - scp->posx) + n = scp->max_posx - scp->posx; + dst = scp->crtat; + src = dst + n; + count = scp->max_posx - (scp->posx + n); + move_down(src, dst, count); + src = dst + count; + fillw(scp->attr | ' ', src, n); + break; + + case '@': /* Insert n chars */ + n = scp->par[0]; if (n < 1) n = 1; + if (n > scp->max_posx - scp->posx) + n = scp->max_posx - scp->posx; + src = scp->crtat; + dst = src + n; + count = scp->max_posx - (scp->posx + n); + move_up(src, dst, count); + fillw(scp->attr | ' ', src, n); + break; + + case 'S': /* scroll up n lines */ + n = scp->par[0]; if (n < 1) n = 1; + bcopy(scp->crt_base + (scp->max_posx * n), + scp->crt_base, + scp->max_posx * (scp->max_posy - n) * + sizeof(u_short)); + fillw(scp->attr | ' ', + scp->crt_base + scp->max_posx * + (scp->max_posy - 1), + scp->max_posx); + break; + + case 'T': /* scroll down n lines */ + n = scp->par[0]; if (n < 1) n = 1; + bcopy(scp->crt_base, + scp->crt_base + (scp->max_posx * n), + scp->max_posx * (scp->max_posy - n) * + sizeof(u_short)); + fillw(scp->attr | ' ', scp->crt_base, scp->max_posx); + break; + + case 'X': /* delete n characters in line */ + n = scp->par[0]; if (n < 1) n = 1; + fillw(scp->attr | ' ', scp->crt_base + scp->posx + + ((scp->max_posx*scp->posy) * sizeof(u_short)), n); + break; + + case 'Z': /* move n tabs backwards */ + n = scp->par[0]; if (n < 1) n = 1; + if ((i = scp->posx & 0xf8) == scp->posx) + i -= 8*n; + else + i -= 8*(n-1); + if (i < 0) + i = 0; + move_crsr(scp, i, scp->posy); + break; + + case '`': /* move cursor to column n */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, n, scp->posy); + break; + + case 'a': /* move cursor n columns to the right */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx + n, scp->posy); + break; + + case 'd': /* move cursor to row n */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx, n); + break; + + case 'e': /* move cursor n rows down */ + n = scp->par[0]; if (n < 1) n = 1; + move_crsr(scp, scp->posx, scp->posy + n); + break; + + case 'm': /* change attribute */ + if (scp->n_par == 0) + n = 0; + else + n = scp->par[0]; + switch (n) { + case 0: /* back to normal */ + scp->attr = scp->std_attr; + break; + case 1: /* highlight (bold) */ + scp->attr &= 0xFF00; + scp->attr |= 0x0800; + break; + case 4: /* highlight (underline) */ + scp->attr &= 0x0F00; + scp->attr |= 0x0800; + break; + case 5: /* blink */ + scp->attr &= 0xFF00; + scp->attr |= 0x8000; + break; + case 7: /* reverse video */ + scp->attr = scp->rev_attr; + break; + case 30: case 31: case 32: case 33: /* set fg color */ + case 34: case 35: case 36: case 37: + scp->attr = (scp->attr & 0xF0FF) + | (ansi_col[(n - 30) & 7] << 8); + break; + case 40: case 41: case 42: case 43: /* set bg color */ + case 44: case 45: case 46: case 47: + scp->attr = (scp->attr & 0x0FFF) + | (ansi_col[(n - 40) & 7] << 12); + break; + } + break; + + case 'x': + if (scp->n_par == 0) + n = 0; + else + n = scp->par[0]; + switch (n) { + case 0: /* reset attributes */ + scp->attr = scp->std_attr = FG_LIGHTGREY << 8; + break; + case 1: /* set ansi background */ + scp->attr = scp->std_attr = + (scp->std_attr & 0x0F00) + | (ansi_col[(scp->par[1])&0x0F] << 12); + break; + case 2: /* set ansi foreground */ + scp->attr = scp->std_attr = + (scp->std_attr & 0xF000) + | (ansi_col[(scp->par[1])&0x0F] << 8); + break; + case 3: /* set ansi attribute directly */ + scp->attr = scp->std_attr = + (scp->par[1] & 0xFF) << 8; + break; + case 5: /* set ansi reverse video background */ + scp->rev_attr = + (scp->rev_attr & 0x0F00) + | (ansi_col[(scp->par[1]) & 0x0F] << 12); + break; + case 6: /* set ansi reverse video foreground */ + scp->rev_attr = + (scp->rev_attr & 0xF000) + | (ansi_col[(scp->par[1]) & 0x0F] << 8); + break; + case 7: /* set ansi reverse video directly */ + scp->rev_attr = (scp->par[1] & 0xFF) << 8; + break; + } + break; + + case 'z': /* switch to (virtual) console n */ + if (scp->n_par == 1) + switch_scr(scp->par[0]); + break; + } + } + else if (scp->esc == 3) { + if (c >= '0' && c <= '9') { + if (scp->n_par < MAX_ESC_PAR) { + if (scp->last_par != scp->n_par) { + scp->last_par = scp->n_par; + scp->par[scp->n_par] = 0; + } + else + scp->par[scp->n_par] *= 10; + scp->par[scp->n_par] += c - '0'; + return; + } + } + scp->n_par = scp->last_par + 1; + switch (c) { + + case ';': + if (scp->n_par < MAX_ESC_PAR) + return; + break; + + case 'A': /* set display border color */ + if (scp->n_par == 1) + scp->border=scp->par[0] & 0xff; + if (scp == cur_scr_stat) + set_border(scp->border); + break; + + case 'B': /* set bell pitch and duration */ + if (scp->n_par == 2) { + scp->bell_pitch = scp->par[0]; + scp->bell_duration = scp->par[1]*10; + } + break; + + case 'C': /* set cursor shape (start & end line) */ + if (scp->n_par == 2) + cursor_shape(scp->par[0], scp->par[1]); + break; + + case 'F': /* set ansi foreground */ + if (scp->n_par == 1) + scp->attr = scp->std_attr = + (scp->std_attr & 0xF000) + | ((scp->par[0] & 0x0F) << 8); + break; + + case 'G': /* set ansi background */ + if (scp->n_par == 1) + scp->attr = scp->std_attr = + (scp->std_attr & 0x0F00) + | ((scp->par[0] & 0x0F) << 12); + break; + + case 'H': /* set ansi reverse video foreground */ + if (scp->n_par == 1) + scp->rev_attr = + (scp->rev_attr & 0xF000) + | ((scp->par[0] & 0x0F) << 8); + break; + + case 'I': /* set ansi reverse video background */ + if (scp->n_par == 1) + scp->rev_attr = + (scp->rev_attr & 0x0F00) + | ((scp->par[0] & 0x0F) << 12); + break; + } + } + scp->esc = 0; +} + + +#define wrtchar(scp, c) ( *scp->crtat = (c), scp->crtat++, scp->posx++ ) + +static void ansi_put(scr_stat *scp, u_char c) +{ + int s; + + if (scp == cur_scr_stat ) + scrn_saver(0); + if (scp->status & UNKNOWN_MODE) + return; + in_putc++; + if (scp->esc) + scan_esc(scp, c); + else switch(c) { + case 0x1B: + scp->esc = 1; + scp->n_par = 0; + break; + case '\t': + do { + wrtchar(scp, scp->attr | ' '); + } while (scp->posx % 8); + break; + case '\b': /* non-destructive backspace */ + if (scp->crtat > scp->crt_base) { + scp->crtat--; + if (scp->posx > 0) + scp->posx--; + else { + scp->posx += scp->max_posx - 1; + scp->posy--; + } + } + break; + case '\r': + move_crsr(scp, 0, scp->posy); + break; + case '\n': + scp->crtat += scp->max_posx; + scp->posy++; + break; + case '\f': + clear_screen(scp); + break; + default: + if (c == 7) { + if (scp == cur_scr_stat) + sysbeep(scp->bell_pitch, scp->bell_duration); + } + /* Print only printables */ + else { + wrtchar(scp, scp->attr | c); + if (scp->posx >= scp->max_posx) { + scp->posx = 0; + scp->posy++; + } + break; + } + } + if (scp->crtat >= scp->crt_base + scp->max_posy * scp->max_posx) { + bcopy(scp->crt_base + scp->max_posx, scp->crt_base, + scp->max_posx * (scp->max_posy - 1) * sizeof(u_short)); + fillw(scp->attr | ' ', + scp->crt_base + scp->max_posx * (scp->max_posy - 1), + scp->max_posx); + scp->crtat -= scp->max_posx; + scp->posy--; + } + s = spltty(); + in_putc--; + splx(s); + if (nx_scr) + switch_scr(nx_scr - 1); +} + + +void consinit(void) +{ + u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/sizeof(u_short), was; + scr_stat *scp; + unsigned cursorat; + int i; + + /* + * catch that once in a blue moon occurence when consinit is called + * TWICE, adding the CGA_BUF offset again -> poooff + * thanks to Christoph Robitchko for finding this one !! + */ + if (crtat != 0) + return; + /* + * Crtat initialized to point to MONO buffer, if not present change + * to CGA_BUF offset. ONLY ADD the difference since locore.s adds + * in the remapped offset at the right time + */ + was = *cp; + *cp = (u_short) 0xA55A; + if (*cp != 0xA55A) { + crtc_addr = MONO_BASE; + } else { + *cp = was; + crtc_addr = COLOR_BASE; + Crtat = Crtat + (CGA_BUF-MONO_BUF)/sizeof(u_short); + } + /* Extract cursor location */ + outb(crtc_addr,14); + cursorat = inb(crtc_addr+1)<<8 ; + outb(crtc_addr,15); + cursorat |= inb(crtc_addr+1); + + crtat = Crtat+ cursorat; + + cons_scr_stat[0].crtat = crtat; + cons_scr_stat[0].crt_base = Crtat; + cons_scr_stat[0].posx = cursorat % COL; + cons_scr_stat[0].posy = cursorat / COL; + cons_scr_stat[0].esc = 0; + cons_scr_stat[0].std_attr = (FG_LIGHTGREY | BG_BLACK) << 8; + cons_scr_stat[0].rev_attr = (FG_BLACK | BG_LIGHTGREY) << 8; + cons_scr_stat[0].attr = (FG_LIGHTGREY | BG_BLACK) << 8; + cons_scr_stat[0].border = BG_BLACK;; + cons_scr_stat[0].max_posx = COL; + cons_scr_stat[0].max_posy = ROW; + cons_scr_stat[0].status = 0; + cons_scr_stat[0].pid = 0; + cons_scr_stat[0].proc = NULL; + cons_scr_stat[0].smode.mode = VT_AUTO; + cons_scr_stat[0].bell_pitch = 800; + cons_scr_stat[0].bell_duration = 10; + clear_screen(&cons_scr_stat[0]); +} + + +static void sput(u_char c, u_char ca) +{ + int i; + scr_stat *scp = &cons_scr_stat[0]; + + if (crtat == 0) + consinit(); + i = scp->attr; + scp->attr = ca << 8; + ansi_put(scp, c); + scp->attr = i; +} + + +static u_char *get_fstr(u_int c, u_int *len) +{ + u_int i; + + if (!(c & FKEY)) + return(NULL); + i = (c & 0xFF) - F_FN; + if (i > n_fkey_tab) + return(NULL); + *len = fkey_tab[i].len; + return(fkey_tab[i].str); +} + + +static update_leds(int which) +{ + u_char xlate_leds[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; + int i; + + kbd_cmd(KB_SETLEDS); /* LED Command */ + kbd_cmd(xlate_leds[which]); + kbd_wait(); +} + + +volatile void reset_cpu(void) +{ + int i; + + while (1) { + kbd_cmd(KB_RESET_CPU); /* Reset Command */ + DELAY(4000000); + kbd_cmd(KB_RESET); /* Keyboard Reset Command */ + } +} + + +/* + * sgetc(noblock) : get a character from the keyboard. + * If noblock = 0 wait until a key is gotten. Otherwise return a 0x100. + */ +u_int sgetc(int noblock) +{ + u_char dt, modifier; + static u_char esc_flag = 0; + u_int state, action; + int i; + struct key_t *key; + +next_code: + kbd_wait(); + /* First see if there is something in the keyboard port */ + if (inb(KB_STAT) & KB_BUF_FULL) + dt = inb(KB_DATA); + else if (noblock) + return(0x100); + else + goto next_code; + + if (cur_scr_stat->status & KBD_RAW_MODE) + return dt; + + /* Check for cntl-alt-del */ + if ((dt == 83) && ctls && alts) + cpu_reset(); + +#if NDDB > 0 + /* Check for cntl-alt-esc */ + if ((dt == 1) && ctls && alts) { + /* if debugger called, try to switch to console 0 */ + if (cur_scr_stat->smode.mode == VT_AUTO && + cons_scr_stat[0].smode.mode == VT_AUTO) + switch_scr(0); + Debugger(); + } +#endif + if (dt == 0xE0 || dt == 0xE1) { + esc_flag = dt; + goto next_code; + } + + if ((dt & 0x7F) >= key_map.n_keys) + goto next_code; + + if (esc_flag == 0xE0) { + switch (dt & 0x7F) { + case 0x2A: /* This may come because the keyboard keeps */ + case 0x36: /* its own caps lock status, we ignore SOS */ + goto next_code; + /* NOT REACHED */ + case 0x1C: /* keypad enter key */ + modifier = 0x59; + break; + case 0x1D: /* right control key */ + modifier = 0x5a; + break; + case 0x35: /* keypad divide key */ + modifier = 0x5b; + break; + case 0x37: /* print scrn key */ + modifier = 0x5c; + break; + case 0x38: /* right alt key (alt gr) */ + modifier = 0x5d; + break; + case 0x47: /* grey home key */ + modifier = 0x5e; + break; + case 0x48: /* grey up arrow key */ + modifier = 0x5f; + break; + case 0x49: /* grey page up key */ + modifier = 0x60; + break; + case 0x4b: /* grey left arrow key */ + modifier = 0x61; + break; + case 0x4d: /* grey right arrow key */ + modifier = 0x62; + break; + case 0x4f: /* grey end key */ + modifier = 0x63; + break; + case 0x50: /* grey down arrow key */ + modifier = 0x64; + break; + case 0x51: /* grey page down key */ + modifier = 0x65; + break; + case 0x52: /* grey insert key */ + modifier = 0x66; + break; + case 0x53: /* grey delete key */ + modifier = 0x67; + break; + default: /* every thing else is ignored */ + goto next_code; + /* NOT REACHED */ + } + dt = (dt & 0x80) | modifier; + } + else if (esc_flag == (u_char)0xE1 && ((dt & 0x7F) == 0x1D)) { + esc_flag = 0x1D; + goto next_code; + } + else if (esc_flag == 0x1D && ((dt & 0x7F) == 0x45)) + dt = (dt & 0x80) | 0x68; + esc_flag = 0; + + state = (shfts ? 1 : 0 ) | (2 * (ctls ? 1 : 0)) | (4 * (alts ? 1 : 0)); + key = &key_map.key[dt & 0x7F]; + if ( ((key->flgs & FLAG_LOCK_C) && (cur_scr_stat->status & CLKED)) + || ((key->flgs & FLAG_LOCK_N) && (cur_scr_stat->status & NLKED)) ) + state ^= 1; + + /* Check for make/break */ + action = key->map[state]; + if (dt & 0x80) { + /* break */ + if (key->spcl & 0x80) { + switch (action) { + case LSH: + shfts &= ~1; + break; + case RSH: + shfts &= ~2; + break; + case LCTR: + ctls &= ~1; + break; + case RCTR: + ctls &= ~2; + break; + case LALT: + alts &= ~1; + break; + case RALT: + alts &= ~2; + break; + } + } + } else { + /* make */ + if (key->spcl & (0x80>>state)) { + switch (action) { + /* LOCKING KEYS */ + case NLK: + if (cur_scr_stat->status & NLKED) + cur_scr_stat->status &= ~NLKED; + else + cur_scr_stat->status |= NLKED; + update_leds(cur_scr_stat->status&LOCK_KEY_MASK); + break; + case CLK: + if (cur_scr_stat->status & CLKED) + cur_scr_stat->status &= ~CLKED; + else + cur_scr_stat->status |= CLKED; + update_leds(cur_scr_stat->status&LOCK_KEY_MASK); + break; + case SLK: + if (cur_scr_stat->status & SLKED) { + cur_scr_stat->status &= ~SLKED; + pcstart(&pccons[get_scr_num(cur_scr_stat)]); + } + else + cur_scr_stat->status |= SLKED; + update_leds(cur_scr_stat->status&LOCK_KEY_MASK); + break; + + /* NON-LOCKING KEYS */ + case LSH: + shfts |= 1; + break; + case RSH: + shfts |= 2; + break; + case LCTR: + ctls |= 1; + break; + case RCTR: + ctls |= 2; + break; + case LALT: + alts |= 1; + break; + case RALT: + alts |= 2; + break; + default: + if (action >= F_SCR && action <= L_SCR) { + switch_scr(action - F_SCR); + break; + } + if (action >= F_FN && action <= L_FN) { + return(action | FKEY); + } + return(action); + } + } + else return(action); + } + goto next_code; +} + +/* -hv- 22-Apr-93: to make init_main more portable */ +void cons_highlight(void) +{ + scr_stat *scp = &cons_scr_stat[0]; + + scp->attr &= 0xFF00; + scp->attr |= 0x0800; +} + +void cons_normal(void) +{ + scr_stat *scp = &cons_scr_stat[0]; + + scp->attr = scp->std_attr; +} + +int getchar(void) +{ + char thechar; + int delay, x; + + pcconsoftc.cs_flags |= CSF_POLLING; + x = splhigh(); + sput('>', FG_RED | BG_BLACK); + thechar = (char) sgetc(0); + pcconsoftc.cs_flags &= ~CSF_POLLING; + splx(x); + switch (thechar) { + default: + if (thechar >= ' ') + sput(thechar, FG_RED | BG_BLACK); + return(thechar); + case cr: + case lf: + sput(cr, FG_RED | BG_BLACK); + sput(lf, FG_RED | BG_BLACK); + return(lf); + case bs: + case del: + sput(bs, FG_RED | BG_BLACK); + sput(' ', FG_RED | BG_BLACK); + sput(bs, FG_RED | BG_BLACK); + return(thechar); + case cntld: + sput('^', FG_RED | BG_BLACK) ; + sput('D', FG_RED | BG_BLACK) ; + sput('\r', FG_RED | BG_BLACK) ; + sput('\n', FG_RED | BG_BLACK) ; + return(0); + } +} + + +int pcmmap(dev_t dev, int offset, int nprot) +{ + if (offset > 0x20000) + return EINVAL; + return i386_btop((VIDEOMEM + offset)); +} + + +static void kbd_wait(void) +{ + int i; + for (i=0; i<10000; i++) + if ((inb(KB_STAT) & KB_READY) == 0) + break; +} + + +static void kbd_cmd(u_char command) +{ + kbd_wait(); + outb(KB_DATA, command); +} + + +static void set_mode(scr_stat *scp) +{ + u_char byte; + + if (scp != cur_scr_stat) + return; + + /* setup video hardware for the given mode */ + switch(scp->mode) { + case TEXT80x25: + outb(crtc_addr, 9); byte = inb(crtc_addr+1); + outb(crtc_addr, 9); outb(crtc_addr+1, byte | 0x0F); + outb(TSIDX, 0x03); outb(TSREG, 0x00); /* select font 0 */ + break; + case TEXT80x50: + outb(crtc_addr, 9); byte = inb(crtc_addr+1); + outb(crtc_addr, 9); outb(crtc_addr+1, (byte & 0xF0) | 0x07); + outb(TSIDX, 0x03); outb(TSREG, 0x05); /* select font 1 */ + break; + default: + return; + } + + /* set border color for this (virtual) console */ + set_border(scp->border); + + /* (re)activate cursor */ + untimeout(cursor_pos, 0); + cursor_pos(); +} + + +static void set_border(int color) +{ + inb(crtc_addr+6); /* reset flip-flop */ + outb(ATC, 0x11); outb(ATC, color); + inb(crtc_addr+6); /* reset flip-flop */ + outb(ATC, 0x20); /* enable Palette */ +} + +static load_font(int segment, int size, char* font) +{ + int ch, line; + u_char val; + + outb(TSIDX, 0x01); val = inb(TSREG); /* blank screen */ + outb(TSIDX, 0x01); outb(TSREG, val | 0x20); + + /* setup vga for loading fonts (graphics plane mode) */ + inb(crtc_addr+6); /* reset flip/flop */ + outb(ATC, 0x30); outb(ATC, 0x01); + outb(TSIDX, 0x02); outb(TSREG, 0x04); + outb(TSIDX, 0x04); outb(TSREG, 0x06); + outb(GDCIDX, 0x04); outb(GDCREG, 0x02); + outb(GDCIDX, 0x05); outb(GDCREG, 0x00); + outb(GDCIDX, 0x06); outb(GDCREG, 0x05); /* addr = a0000, 64kb */ + for (ch=0; ch < 256; ch++) + for (line=0; line < size; line++) + *((char *)atdevbase+(segment*0x4000)+(ch*32)+line) = + font[(ch*size)+line]; + /* setup vga for text mode again */ + inb(crtc_addr+6); /* reset flip/flop */ + outb(ATC, 0x30); outb(ATC, 0x0C); + outb(TSIDX, 0x02); outb(TSREG, 0x03); + outb(TSIDX, 0x04); outb(TSREG, 0x02); + outb(GDCIDX, 0x04); outb(GDCREG, 0x00); + outb(GDCIDX, 0x05); outb(GDCREG, 0x10); + if (crtc_addr == MONO_BASE) { + outb(GDCIDX, 0x06); outb(GDCREG, 0x0A); /* addr = b0000, 32kb */ + } + else { + outb(GDCIDX, 0x06); outb(GDCREG, 0x0E); /* addr = b8000, 32kb */ + } + outb(TSIDX, 0x01); val = inb(TSREG); /* unblank screen */ + outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); +} + + +static void load_palette(void) +{ + int i; + + outb(PIXMASK, 0xFF); /* no pixelmask */ + outb(PALWADR, 0x00); + for (i=0x00; i<0x300; i++) + outb(PALDATA, palette[i]); + inb(crtc_addr+6); /* reset flip/flop */ + outb(ATC, 0x20); /* enable palette */ +} + +static void save_palette(void) +{ + int i; + + outb(PALRADR, 0x00); + for (i=0x00; i<0x300; i++) + palette[i] = inb(PALDATA); + inb(crtc_addr+6); /* reset flip/flop */ +} + + +static change_winsize(struct tty *tp, int x, int y) +{ + if (tp->t_winsize.ws_col != x || tp->t_winsize.ws_row != y) { + tp->t_winsize.ws_col = x; + tp->t_winsize.ws_row = y; + pgsignal(tp->t_pgrp, SIGWINCH, 1); + } +} + +#endif /* NSC */