|
|
1.1 root 1: //
2: // nono
1.1.1.4 ! root 3: // Copyright (C) 2020 nono project
! 4: // Licensed under nono-license.txt
1.1 root 5: //
6:
1.1.1.4 ! root 7: // キーボードは MFP の USART に繋がっている。
! 8: // MFP USART の RR 線 (Receiver Ready) は受信可能なら 'H'、受信中は 'L' に
! 9: // なっている。キーボードは RR が 'H' の時だけデータを送信する。
! 10: // また、システムポート#4 の KEY CTRL = 0 (キーデータ送信不可) はこの RR を
! 11: // 'L' に落とす論理回路になっている。
! 12: // キーボードからの送信は 2400bps、ストップビット1、パリティなしなので、
! 13: // 1バイトの送信に 3.75 msec かかる。
! 14: // 実装では、キーボードは MFP の RR が 'H' なら MFP にキーデータを送信。
! 15: // MFP 側で RR を 'L' にして 3.75 msec をイベントで待った後、キーを処理して
! 16: // RR を 'H' に戻すことにする。
! 17:
1.1 root 18: #include "x68kkbd.h"
19: #include "mfp.h"
20:
21: // コンストラクタ
22: X68030Keyboard::X68030Keyboard()
23: {
1.1.1.4 ! root 24: led.resize(7);
1.1.1.3 root 25: }
26:
27: // デストラクタ
28: X68030Keyboard::~X68030Keyboard()
29: {
30: }
31:
1.1.1.4 ! root 32: // 本体リセットスイッチによるリセット
! 33: void
! 34: X68030Keyboard::ResetHard()
1.1.1.3 root 35: {
1.1.1.4 ! root 36: rept_delay = 500;
! 37: rept_time = 110;
! 38:
! 39: for (int i = 0; i < led.size(); i++) {
! 40: led[i] = false;
! 41: }
! 42: led_darkness = 0;
1.1 root 43: }
44:
45: // キーを押した
46: void
47: X68030Keyboard::MakeKey(uint keycode)
48: {
49: uint x68kkey;
50:
51: // 共通キーコードから X680x0 キーコードに
52: x68kkey = keycode2x68kkey(keycode);
53:
54: // X680x0 にないキーは無視
55: if (x68kkey == NoKey) {
56: return;
57: }
58:
1.1.1.4 ! root 59: // LED は MPU 側から点灯/消灯指示が来るのでここでは何もしなくてよい
1.1 root 60:
1.1.1.4 ! root 61: putlog(1, "MakeKey %d(%s)", x68kkey, keyname[x68kkey]);
! 62: SendKey(x68kkey);
1.1 root 63: }
64:
65: // キーを離した
66: void
67: X68030Keyboard::BreakKey(uint keycode)
68: {
69: uint x68kkey;
70:
71: // 共通キーコードから X680x0 キーコードに
72: x68kkey = keycode2x68kkey(keycode);
73:
74: // X680x0 にないキーは無視
75: if (x68kkey == NoKey) {
76: return;
77: }
78:
79: putlog(2, "BreakKey %d(%s)", x68kkey, keyname[x68kkey]);
1.1.1.4 ! root 80: SendKey(x68kkey | 0x80);
1.1 root 81: }
82:
1.1.1.2 root 83: // マウス入力
84: void
85: X68030Keyboard::MouseInput(int x, int y, bool rb, bool lb, bool mb)
86: {
87: }
88:
1.1.1.4 ! root 89: // キーデータを送信
! 90: void
! 91: X68030Keyboard::SendKey(uint data)
! 92: {
! 93: if (gMFP->IsRR()) {
! 94: gMFP->Rx(data);
! 95: }
! 96: }
! 97:
! 98: // ホストからの制御
! 99: void
! 100: X68030Keyboard::Command(uint32 data)
! 101: {
! 102: if (data < 0x40) {
! 103: // $00-$3f TV 制御
! 104: // (実装不要)
! 105: putlog(2, "Command TV 制御 $%02x", (data & 0x1f));
! 106:
! 107: } else if (data < 0x48) {
! 108: // $40-$47 MSCTRL 信号制御
! 109: // こいつは頻度が高いのでログレベルを上げておく
! 110: putlog(3, "Command MSCTRL 制御 %d", (data & 1));
! 111:
! 112: } else if (data < 0x50) {
! 113: // $48-$4f キーデータ送出許可
! 114: putlog(1, "Command キー送出許可 %d (未実装)", (data & 1));
! 115:
! 116: } else if (data < 0x54) {
! 117: // $50-$53 ディスプレイ制御モード選択
! 118: // (実装不要)
! 119: putlog(2, "Command ディスプレイ制御 X68000モード %d", (data & 1));
! 120:
! 121: } else if (data < 0x58) {
! 122: // $54-$57 LED 明るさ選択
! 123: // 0 が明るく 3 が暗いので、明るさというより暗さ。
! 124: led_darkness = (data & 3);
! 125: putlog(1, "Command LED 明るさ %d", led_darkness);
! 126:
! 127: } else if (data < 0x5c) {
! 128: // $58-$5b 本体からのディスプレイ制御許可
! 129: // (実装不要)
! 130: putlog(2, "Command 本体からディスプレイ制御 %d", (data & 1));
! 131:
! 132: } else if (data < 0x60) {
! 133: // $5c-$5f OPT.2 によるディスプレイ制御許可
! 134: // (実装不要)
! 135: putlog(2, "Command OPT2からディスプレイ制御 %d", (data & 1));
! 136:
! 137: } else if (data < 0x70) {
! 138: // $60-$6f リピートまでの時間
! 139: rept_delay = 200 + (data & 15) * 100;
! 140: putlog(1, "Command Repeat Delay %d (%d msec)", (data & 15), rept_delay);
! 141:
! 142: } else if (data < 0x80) {
! 143: // $70-$7f リピート間隔
! 144: rept_time = 30 + (data & 15) * (data & 15) * 5;
! 145: putlog(1, "Command Repeat time %d (%d msec)", (data & 15), rept_time);
! 146:
! 147: } else {
! 148: // $80-$ff LED 制御
! 149: data &= 0x7f;
! 150: putlog(1, "Command LED 制御 $%02x", data);
! 151: uint32 b = 0x01;
! 152: for (int i = 0; i < led.size(); i++) {
! 153: // data は %0 で点灯、led[] は true で点灯
! 154: led[i] = ((data & b) == 0);
! 155: b <<= 1;
! 156: }
! 157: }
! 158: }
! 159:
1.1 root 160: // 共通キーコードを X680x0 キーコードに変換して返す。
161: // X680x0 キーがなければ NoKey を返す。
162: uint
163: X68030Keyboard::keycode2x68kkey(uint keycode)
164: {
165: if (keycode >= countof(keycode2x68kkey_table)) {
166: return NoKey;
167: }
168:
169: return keycode2x68kkey_table[keycode];
170: }
171:
172: // キーコード変換表
173: // 共通キーコードから X680x0 キーコードに変換する。
174: /*static*/ const uint
175: X68030Keyboard::keycode2x68kkey_table[133] = {
176: NoKey, // [00]
177: X68kKey_BREAK, // [01]
178: X68kKey_COPY, // [02]
179: X68kKey_romaji, // [03]
1.1.1.4 ! root 180: X68kKey_code, // [04]
1.1 root 181: X68kKey_kigou, // [05]
182: X68kKey_touroku, // [06]
183: X68kKey_HELP, // [07]
184: X68kKey_HOME, // [08]
185: X68kKey_TAB, // [09]
186: X68kKey_CTRL, // [0a]
187: X68kKey_kana, // [0b]
188: X68kKey_SHIFT, // [0c]
189: NoKey, // [0d]
190: X68kKey_CAPS, // [0e]
191: NoKey, // [0f]
192:
193: X68kKey_ESC, // [10]
194: X68kKey_BS, // [11]
195: X68kKey_enter, // [12]
196: X68kKey_INS, // [13]
197: X68kKey_space, // [14]
198: X68kKey_DEL, // [15]
199: NoKey, // [16]
200: NoKey, // [17]
201: NoKey, // [18]
202: NoKey, // [19]
203: NoKey, // [1a]
204: NoKey, // [1b]
205: X68kKey_up, // [1c]
206: X68kKey_left, // [1d]
207: X68kKey_right, // [1e]
208: X68kKey_down, // [1f]
209:
210: X68kKey_ROLLUP, // [20]
211: X68kKey_ROLLDOWN, // [21]
212: X68kKey_1, // [22]
213: X68kKey_2, // [23]
214: X68kKey_3, // [24]
215: X68kKey_4, // [25]
216: X68kKey_5, // [26]
217: X68kKey_6, // [27]
218: X68kKey_7, // [28]
219: X68kKey_8, // [29]
220: X68kKey_9, // [2a]
221: X68kKey_0, // [2b]
222: X68kKey_minus, // [2c]
223: X68kKey_circum, // [2d]
224: X68kKey_backslash, // [2e]
225: X68kKey_UNDO, // [2f]
226:
227: X68kKey_OPT1, // [30]
228: X68kKey_OPT2, // [31]
229: X68kKey_Q, // [32]
230: X68kKey_W, // [33]
231: X68kKey_E, // [34]
232: X68kKey_R, // [35]
233: X68kKey_T, // [36]
234: X68kKey_Y, // [37]
235: X68kKey_U, // [38]
236: X68kKey_I, // [39]
237: X68kKey_O, // [3a]
238: X68kKey_P, // [3b]
239: X68kKey_at, // [3c]
240: X68kKey_bracketleft, // [3d]
241: X68kKey_hira, // [3e]
242: X68kKey_zenkaku, // [3f]
243:
244: NoKey, // [40]
245: NoKey, // [41]
246: X68kKey_A, // [42]
247: X68kKey_S, // [43]
248: X68kKey_D, // [44]
249: X68kKey_F, // [45]
250: X68kKey_G, // [46]
251: X68kKey_H, // [47]
252: X68kKey_J, // [48]
253: X68kKey_K, // [49]
254: X68kKey_L, // [4a]
255: X68kKey_semicolon, // [4b]
256: X68kKey_colon, // [4c]
257: X68kKey_bracketright, // [4d]
258: NoKey, // [4e]
259: NoKey, // [4f]
260:
261: NoKey, // [50]
262: NoKey, // [51]
263: X68kKey_Z, // [52]
264: X68kKey_X, // [53]
265: X68kKey_C, // [54]
266: X68kKey_V, // [55]
267: X68kKey_B, // [56]
268: X68kKey_M, // [57]
269: X68kKey_N, // [58]
270: X68kKey_comma, // [59]
271: X68kKey_period, // [5a]
272: X68kKey_slash, // [5b]
273: X68kKey_underscore, // [5c]
274: NoKey, // [5d]
275: NoKey, // [5e]
276: NoKey, // [5f]
277:
278: NoKey, // [60]
279: X68kKey_PAD_plus, // [61]
280: X68kKey_PAD_minus, // [62]
281: X68kKey_PAD_7, // [63]
282: X68kKey_PAD_8, // [64]
283: X68kKey_PAD_9, // [65]
284: X68kKey_PAD_4, // [66]
285: X68kKey_PAD_5, // [67]
286: X68kKey_PAD_6, // [68]
287: X68kKey_PAD_1, // [69]
288: X68kKey_PAD_2, // [6a]
289: X68kKey_PAD_3, // [6b]
290: X68kKey_PAD_0, // [6c]
291: X68kKey_PAD_decimal, // [6d]
292: X68kKey_PAD_enter, // [6e]
293: X68kKey_PAD_CLR, // [6f]
294:
295: NoKey, // [70]
296: NoKey, // [71]
297: X68kKey_F1, // [72]
298: X68kKey_F2, // [73]
299: X68kKey_F3, // [74]
300: X68kKey_F4, // [75]
301: X68kKey_F5, // [76]
302: X68kKey_F6, // [77]
303: X68kKey_F7, // [78]
304: X68kKey_F8, // [79]
305: X68kKey_F9, // [7a]
306: X68kKey_F10, // [7b]
307: X68kKey_PAD_multiply, // [7c]
308: X68kKey_PAD_divide, // [7d]
309: X68kKey_PAD_equal, // [7e]
310: X68kKey_PAD_comma, // [7f]
311:
312: X68kKey_XF1, // [80]
313: X68kKey_XF2, // [81]
314: X68kKey_XF3, // [82]
315: X68kKey_XF4, // [83]
316: X68kKey_XF5, // [84]
317: };
318:
319: /*static*/ const char * const
320: X68030Keyboard::keyname[] =
321: {
322: "", // 00
323: "ESC", // 01
324: "1!", // 02
325: "2\"", // 03
326: "3#", // 04
327: "4$", // 05
328: "5%", // 06
329: "6&", // 07
330: "7'", // 08
331: "8(", // 09
332: "9)", // 0a
333: "0", // 0b
334: "-=", // 0c
335: "^~", // 0d
336: "\\|", // 0e
337: "BS", // 0f
338:
339: "TAB", // 10
340: "Q", // 11
341: "W", // 12
342: "E", // 13
343: "R", // 14
344: "T", // 15
345: "Y", // 16
346: "U", // 17
347: "I", // 18
348: "O", // 19
349: "P", // 1a
350: "@`", // 1b
351: "[{", // 1c
352: "Enter", // 1d
353: "A", // 1e
354: "S", // 1f
355:
356: "D", // 20
357: "F", // 21
358: "G", // 22
359: "H", // 23
360: "J", // 24
361: "K", // 25
362: "L", // 26
363: ";+", // 27
364: ":*", // 28
365: "]}", // 29
366: "Z", // 2a
367: "X", // 2b
368: "C", // 2c
369: "V", // 2d
370: "B", // 2e
371: "N", // 2f
372:
373: "M", // 30
374: ",<", // 31
375: ".>", // 32
376: "/?", // 33
377: " _", // 34
378: "Space", // 35
379: "HOME", // 36
380: "DEL", // 37
381: "ROLLUP", // 38
382: "ROLLDOWN", // 39
383: "UNDO", // 3a
384: "←", // 3b
385: "↑", // 3c
386: "→", // 3d
387: "↓", // 3e
388: "PADCLR", // 3f
389:
390: "PAD/", // 40
391: "PAD*", // 41
392: "PAD-", // 42
393: "PAD7", // 43
394: "PAD8", // 44
395: "PAD9", // 45
396: "PAD+", // 46
397: "PAD4", // 47
398: "PAD5", // 48
399: "PAD6", // 49
400: "PAD=", // 4a
401: "PAD1", // 4b
402: "PAD2", // 4c
403: "PAD3", // 4d
404: "PADEnter", // 4e
405: "PAD0", // 4f
406:
407: "PAD,", // 50
408: "PAD.", // 51
409: "記号", // 52
410: "登録", // 53
411: "HELP", // 54
412: "XF1", // 55
413: "XF2", // 56
414: "XF3", // 57
415: "XF4", // 58
416: "XF5", // 59
417: "かな", // 5a
418: "ローマ字", // 5b
419: "コード", // 5c
420: "CAPS", // 5d
421: "INS", // 5e
422: "ひらがな", // 5f
423:
424: "全角", // 60
425: "BREAK", // 61
426: "COPY", // 62
427: "F1", // 63
428: "F2", // 64
429: "F3", // 65
430: "F4", // 66
431: "F5", // 67
432: "F6", // 68
433: "F7", // 69
434: "F8", // 6a
435: "F9", // 6b
436: "F10", // 6c
437: "", // 6d
438: "", // 6e
439: "", // 6f
440:
441: "SHIFT", // 70
442: "CTRL", // 71
443: "OPT1", // 72
444: "OPT2", // 73
445: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.