source: buchla-emu/emu/kbd.c@ a2b296e

Last change on this file since a2b296e was 18cbd53, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Support sliders.

  • Property mode set to 100644
File size: 4.6 KB
Line 
1/*
2 * Copyright (C) 2017 The Contributors
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * A copy of the GNU General Public License can be found in the file
15 * "gpl.txt" in the top directory of this repository.
16 */
17
18#include <all.h>
19
20#define ver(...) _ver(kbd_verbose, 0, __VA_ARGS__)
21#define ver2(...) _ver(kbd_verbose, 1, __VA_ARGS__)
22#define ver3(...) _ver(kbd_verbose, 2, __VA_ARGS__)
23
24int32_t kbd_verbose = 0;
25
26#define BUF_SZ 16
27
28static int32_t buf_hd = 0;
29static int32_t buf_tl = 0;
30static uint8_t buf[BUF_SZ];
31
32static uint8_t reg = 0;
33static bool irq = false;
34
35static void xmit(void)
36{
37 ver2("kbd xmit %d %d", buf_tl, buf_hd);
38
39 if (buf_tl >= buf_hd) {
40 return;
41 }
42
43 reg = buf[buf_tl % BUF_SZ];
44 irq = true;
45 ver2("kbd xmit 0x%02x", reg);
46
47 ++buf_tl;
48
49 if (buf_tl >= BUF_SZ) {
50 buf_hd -= BUF_SZ;
51 buf_tl -= BUF_SZ;
52 ver2("kbd adj %d %d", buf_tl, buf_hd);
53 }
54}
55
56static void out(uint8_t c)
57{
58 ver2("kbd out %d %d 0x%02x", buf_tl, buf_hd, c);
59
60 if (SDL_LockMutex(cpu_mutex) < 0) {
61 fail("SDL_LockMutex() failed: %s", SDL_GetError());
62 }
63
64 if (buf_hd >= buf_tl + BUF_SZ) {
65 err("keyboard port losing data");
66 }
67 else {
68 buf[buf_hd % BUF_SZ] = c;
69 ++buf_hd;
70
71 if (!irq) {
72 xmit();
73 }
74 }
75
76 if (SDL_UnlockMutex(cpu_mutex) < 0) {
77 fail("SDL_UnlockMutex() failed: %s", SDL_GetError());
78 }
79}
80
81static void but_on(int32_t sig)
82{
83 out((uint8_t)(0x80 | sig));
84 out(0x01);
85}
86
87static void but_off(int32_t sig)
88{
89 out((uint8_t)(0x80 | sig));
90 out(0x00);
91}
92
93static void key_touch(int32_t sig, int32_t val)
94{
95 out((uint8_t)(0x80 | sig));
96 out(0x01);
97 out((uint8_t)val);
98}
99
100static void key_off(int32_t sig)
101{
102 out((uint8_t)(0x80 | sig));
103 out(0x00);
104}
105
106static void slid(int32_t sig, bool on, int32_t val)
107{
108 out((uint8_t)(0x80 | sig));
109 out(on ? 0x01 : 0x00);
110 out((uint8_t)val);
111}
112
113#if defined NOT_YET
114static void pot(int32_t sig, int32_t val)
115{
116 out((uint8_t)(0x80 | sig));
117 out((uint8_t)val);
118}
119#endif
120
121static void vid_key(SDL_KeyboardEvent *ev, bool dn)
122{
123 if ((ev->keysym.mod & KMOD_SHIFT) != 0 &&
124 ev->keysym.sym >= SDLK_a && ev->keysym.sym <= SDLK_x) {
125 int32_t i = ev->keysym.sym - SDLK_a;
126 ver2("kbd key %d %s", i, dn ? "dn" : "up");
127
128 if (dn) {
129 key_touch(1 + i, 0x7f);
130 }
131 else {
132 key_off(1 + i);
133 }
134
135 return;
136 }
137
138 int32_t sig;
139
140 if (ev->keysym.sym >= SDLK_0 && ev->keysym.sym <= '9') {
141 int32_t i = ev->keysym.sym - SDLK_0;
142 ver2("kbd dat %d %s", i, dn ? "dn" : "up");
143 sig = 60 + i;
144 }
145 else {
146 switch (ev->keysym.sym) {
147 case SDLK_x:
148 ver2("kbd x %s", dn ? "dn" : "up");
149 sig = 70;
150 break;
151
152 case SDLK_e:
153 ver2("kbd e %s", dn ? "dn" : "up");
154 sig = 71;
155 break;
156
157 case SDLK_m:
158 ver2("kbd m %s", dn ? "dn" : "up");
159 sig = 72;
160 break;
161
162 default:
163 return;
164 }
165 }
166
167 if (dn) {
168 but_on(sig);
169 }
170 else {
171 but_off(sig);
172 }
173}
174
175static void lcd_key(SDL_KeyboardEvent *ev, bool dn)
176{
177 if ((ev->keysym.mod & KMOD_CTRL) != 0 &&
178 ev->keysym.sym >= SDLK_a && ev->keysym.sym <= SDLK_n) {
179 int32_t i = ev->keysym.sym - SDLK_a;
180 ver2("kbd lcd %d %s", i, dn ? "dn" : "up");
181
182 if (dn) {
183 but_on(39 + i);
184 }
185 else {
186 but_off(39 + i);
187 }
188
189 return;
190 }
191
192 if (ev->keysym.sym >= SDLK_a && ev->keysym.sym <= SDLK_n) {
193 static int32_t lev[14] = {
194 64, 0, 0, 0, 0, 64, 64, 64, 64, 0, 0, 0, 64, 0
195 };
196
197 int32_t i = ev->keysym.sym - SDLK_a;
198 int32_t val = lev[i];
199
200 if (!dn) {
201 if ((ev->keysym.mod & KMOD_SHIFT) != 0) {
202 val = val > 10 ? val - 10 : 0;
203 }
204 else {
205 val = val < 117 ? val + 10 : 127;
206 }
207 }
208
209 ver2("kbd sli %d %s %d", i, dn ? "dn" : "up", val);
210 slid(25 + i, dn, val);
211
212 lev[i] = val;
213 return;
214 }
215}
216
217void kbd_key(SDL_KeyboardEvent *ev, bool vid, bool dn)
218{
219 if (vid) {
220 vid_key(ev, dn);
221 }
222 else {
223 lcd_key(ev, dn);
224 }
225}
226
227void kbd_init(void)
228{
229 ver("kbd init");
230}
231
232void kbd_quit(void)
233{
234 ver("kbd quit");
235}
236
237bool kbd_exec(void)
238{
239 ver3("kbd exec");
240 return irq;
241}
242
243uint32_t kbd_read(uint32_t off, int32_t sz)
244{
245 ver2("kbd rd %u:%d", off, sz * 8);
246
247 if (sz != 1 || off > 0) {
248 fail("invalid kbd rd %u:%d", off, sz * 8);
249 }
250
251 irq = false;
252 uint32_t res = reg;
253
254 xmit();
255
256 return res;
257}
258
259void kbd_write(uint32_t off, int32_t sz, uint32_t val)
260{
261 ver2("kbd wr %u:%d 0x%0*x", off, sz * 8, sz * 2, val);
262 fail("invalid kbd wr %u:%d", off, sz * 8);
263}
Note: See TracBrowser for help on using the repository browser.