3 * (C) 2018 by Andreas Eversberg <jolly@eversberg.eu>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
28 static struct keycodes {
32 { "A", 0x20 }, { "B", 0x35 }, { "C", 0x33 }, { "D", 0x22 },
33 { "E", 0x12 }, { "F", 0x23 }, { "G", 0x24 }, { "H", 0x25 },
34 { "I", 0x17 }, { "J", 0x26 }, { "K", 0x27 }, { "L", 0x28 },
35 { "M", 0x37 }, { "N", 0x36 }, { "O", 0x18 }, { "P", 0x19 },
36 { "Q", 0x10 }, { "R", 0x13 }, { "S", 0x21 }, { "T", 0x14 },
37 { "U", 0x16 }, { "V", 0x34 }, { "W", 0x11 }, { "X", 0x32 },
38 { "Y", 0x15 }, { "Z", 0x31 },
40 { "0", 0x0A }, { "1", 0x01 }, { "2", 0x02 }, { "3", 0x03 },
41 { "4", 0x04 }, { "5", 0x05 }, { "6", 0x06 }, { "7", 0x07 },
42 { "8", 0x08 }, { "9", 0x09 },
44 { "NP0", 0x0F }, { "NP1", 0x1D }, { "NP2", 0x1E }, { "NP3", 0x1F },
45 { "NP4", 0x2D }, { "NP5", 0x2E }, { "NP6", 0x2F }, { "NP7", 0x3D },
46 { "NP8", 0x3E }, { "NP9", 0x3F },
48 { "NPDIV", 0x5C }, { "NPMUL", 0x5D }, { "NPSUB", 0x4A },
49 { "NPADD", 0x5E }, { "NPDEL", 0x3C }, { "NPLPAREN", 0x5A },
52 { "F1", 0x50 }, { "F2", 0x51 }, { "F3", 0x52 }, { "F4", 0x53 },
53 { "F5", 0x54 }, { "F6", 0x55 }, { "F7", 0x56 }, { "F8", 0x57 },
54 { "F9", 0x58 }, { "F10", 0x59 },
56 { "UP", 0x4C }, { "DN", 0x4D }, { "LF", 0x4F }, { "RT", 0x4E },
58 { "SPC", 0x40 }, { "BS", 0x41 }, { "TAB", 0x42 }, { "ENT", 0x43 },
59 { "RET", 0x44 }, { "ESC", 0x45 }, { "DEL", 0x46 },
61 { "LSH", 0x60 }, { "RSH", 0x61 }, { "CAPSLOCK", 0x62 },
62 { "CTRL", 0x63 }, { "LALT", 0x64 }, { "RALT", 0x65 }, { "LAMI", 0x66 },
63 { "RAMI", 0x67 }, { "HELP", 0x5F },
65 { "LBRACKET", 0x1A }, { "RBRACKET", 0x1B }, { "SEMICOLON", 0x29 },
66 { "COMMA", 0x38 }, { "PERIOD", 0x39 }, { "SLASH", 0x3A },
67 { "BACKSLASH", 0x0D }, { "QUOTE", 0x2A }, { "NUMBERSIGN", 0x2B },
68 { "LTGT", 0x30 }, { "BACKQUOTE", 0x00 }, { "MINUS", 0x0B },
74 static uint8_t buffer[16];
75 static int buffer_size = sizeof(buffer), buffer_len = 0;
76 static uint32_t keydown[4] = {0, 0, 0, 0};
78 #define ROL(v) ((v << 1) | (v >> 7))
80 #define CIAASDR 0xbfec00
81 #define CIAAICR 0xbfed00
82 #define CIAACRA 0xbfee00
84 uint16_t emulate_keyboard_read(uint32_t address)
97 value = buffer[--buffer_len];
98 /* rotate and negate */
101 printf("sending key code %02x\n", buffer[buffer_len]);
103 for (i = 0; i < buffer_len; i++)
104 buffer[i] = buffer[i + 1];
105 return 0xff00 | value;
111 void set_key(const char *key, int down)
113 int code = -1, isdown;
116 for (i = 0; keycodes[i].key; i++) {
117 if (!strcmp(keycodes[i].key, key)) {
118 code = keycodes[i].code;
122 if (code < 0 || code >= 0x80) {
123 fprintf(stderr, "Key code '%s' unknown, please fix!\n", key);
127 isdown = (keydown[code >> 5] >> (code & 0x1f)) & 1;
130 // printf("key already down\n");
133 keydown[code >> 5] |= (1 << (code & 0x1f));
136 // printf("key already up\n");
139 keydown[code >> 5] &= ~(1 << (code & 0x1f));
143 if (buffer_len == buffer_size) {
144 fprintf(stderr, "keyboard buffer overflow\n");
148 buffer[buffer_len++] = code;
150 printf("Converting key '%s' to code 0x%02x\n", key, code);