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

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

More accurate key up/down.

  • Property mode set to 100644
File size: 3.7 KB
RevLine 
[a06aa8b]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
[2147e53]15 * "gpl.txt" in the top directory of this repository.
[a06aa8b]16 */
17
18#include <all.h>
19
[4c71d39]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__)
[a06aa8b]23
[4c71d39]24int32_t kbd_verbose = 0;
[a06aa8b]25
[4ed9bfe]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
[d021bbb]106#if defined NOT_YET
[4ed9bfe]107static void pot_128(int32_t sig, int32_t val)
108{
109 out((uint8_t)(0x80 | sig));
110 out((uint8_t)val);
111}
112
113static void pot_256(int32_t sig, int32_t val)
114{
115 out((uint8_t)(0x80 | sig));
116 out((uint8_t)((val >> 7) & 0x01));
117 out((uint8_t)(val & 0x7f));
118}
119#endif
120
[ca77925]121void kbd_key(SDL_KeyboardEvent *ev, bool dn)
[4ed9bfe]122{
[d021bbb]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;
[ca77925]126 ver2("kbd key %d %s", i, dn ? "dn" : "up");
[d021bbb]127
[ca77925]128 if (dn) {
[d021bbb]129 key_touch(1 + i, 0x7f);
130 }
131 else {
132 key_off(1 + i);
133 }
134
[ca77925]135 return;
[d021bbb]136 }
[4ed9bfe]137
[ca77925]138 int32_t sig;
[4ed9bfe]139
[ca77925]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;
[4ed9bfe]150 break;
151
[ca77925]152 case SDLK_e:
153 ver2("kbd e %s", dn ? "dn" : "up");
154 sig = 71;
[4ed9bfe]155 break;
156
[ca77925]157 case SDLK_m:
158 ver2("kbd m %s", dn ? "dn" : "up");
159 sig = 72;
[4ed9bfe]160 break;
[ca77925]161
162 default:
163 return;
[4ed9bfe]164 }
165 }
[ca77925]166
167 if (dn) {
168 but_on(sig);
169 }
170 else {
171 but_off(sig);
172 }
[4ed9bfe]173}
174
[a06aa8b]175void kbd_init(void)
176{
177 ver("kbd init");
178}
179
180void kbd_quit(void)
181{
182 ver("kbd quit");
183}
184
[3c30832]185bool kbd_exec(void)
[a06aa8b]186{
[4c71d39]187 ver3("kbd exec");
[4ed9bfe]188 return irq;
[a06aa8b]189}
190
191uint32_t kbd_read(uint32_t off, int32_t sz)
192{
[4c71d39]193 ver2("kbd rd %u:%d", off, sz * 8);
[4ed9bfe]194
195 if (sz != 1 || off > 0) {
196 fail("invalid kbd rd %u:%d", off, sz * 8);
197 }
198
199 irq = false;
200 uint32_t res = reg;
201
202 xmit();
203
204 return res;
[a06aa8b]205}
206
207void kbd_write(uint32_t off, int32_t sz, uint32_t val)
208{
[4c71d39]209 ver2("kbd wr %u:%d 0x%0*x", off, sz * 8, sz * 2, val);
[4ed9bfe]210 fail("invalid kbd wr %u:%d", off, sz * 8);
[a06aa8b]211}
Note: See TracBrowser for help on using the repository browser.