Annotation of nono/vm/lunakbd.cpp, revision 1.1.1.12

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.2   root        7: // キーボードとマウス
                      8: //
                      9: // キーボード/マウスからシリアルポートへの入力は、1バイトの送信自体に約1msec
                     10: // (9600bps、スタートビット1、ストップビット1) で送信後に 1msec 空けるそう
                     11: // なので、ここでは単純に 2msec を1スロットとする。
                     12: 
1.1       root       13: #include "lunakbd.h"
                     14: #include "sio.h"
1.1.1.12! root       15: #include "uimessage.h"
1.1       root       16: 
                     17: // コンストラクタ
                     18: LunaKeyboard::LunaKeyboard()
                     19: {
1.1.1.4   root       20:        led.resize(2);
1.1       root       21: 
1.1.1.12! root       22:        event.func = (DeviceCallback_t)&LunaKeyboard::Callback;
        !            23:        event.SetName("Keyboard/Mouse");
1.1.1.10  root       24: 
                     25:        monitor.func = (MonitorCallback_t)&LunaKeyboard::MonitorUpdate;
1.1.1.12! root       26:        monitor.SetSize(40, 4);
1.1.1.10  root       27:        monitor.Regist(ID_MONITOR_KEYBOARD);
1.1       root       28: }
                     29: 
                     30: // デストラクタ
                     31: LunaKeyboard::~LunaKeyboard()
                     32: {
                     33: }
                     34: 
1.1.1.9   root       35: // 電源オン
                     36: bool
                     37: LunaKeyboard::PowerOn()
                     38: {
                     39:        // XXX リセットはマウスには届かないような気がするので
                     40:        // 電源オンで初期化。
                     41:        mouse_x = 0;
                     42:        mouse_y = 0;
                     43:        mouse_r = false;
                     44:        mouse_l = false;
                     45:        mouse_m = false;
                     46:        prev_r = false;
                     47:        prev_l = false;
                     48:        prev_m = false;
                     49: 
1.1.1.12! root       50:        // ブザー停止
        !            51:        buzzer_on = false;
        !            52: 
1.1.1.9   root       53:        return true;
                     54: }
                     55: 
1.1.1.2   root       56: // リセット
                     57: void
                     58: LunaKeyboard::ResetHard()
                     59: {
1.1.1.9   root       60:        inherited::ResetHard();
                     61: 
1.1.1.6   root       62:        // 動作中のタイマーは一旦とめる
1.1.1.12! root       63:        event.Stop();
1.1.1.6   root       64: 
1.1.1.12! root       65:        // マウスサンプリングは電源オン時から有効
        !            66:        MouseOn();
1.1.1.2   root       67: }
                     68: 
                     69: // モニター
1.1.1.5   root       70: void
1.1.1.10  root       71: LunaKeyboard::MonitorUpdate(Monitor *, TextScreen& screen)
1.1.1.2   root       72: {
1.1.1.12! root       73:        int x;
        !            74:        int y;
        !            75:        int mx;
        !            76:        int my;
        !            77: 
1.1.1.10  root       78:        screen.Clear();
1.1.1.12! root       79:        y = 0;
1.1.1.2   root       80: 
1.1.1.12! root       81:        // 0123456789012345678901234567890123456789
        !            82:        // LED:    CAP Kana
        !            83:        // Buzzer: 150msec 6000Hz
        !            84:        // Mouse:  sampling=off x=-999 y=-999 L M R
        !            85:        x = 8;
        !            86:        screen.Puts(0,  y, "LED:");
        !            87:        screen.Puts(x,  y, TA::OnOff(led[1]), "CAP");
        !            88:        screen.Puts(x + 4, y, TA::OnOff(led[0]), "Kana");
        !            89:        y++;
        !            90:        screen.Puts(0,  y, "Buzzer:");
        !            91:        screen.Print(x,  y, buzzer_on ? TA::Normal : TA::Disable,
        !            92:                "%umsec %uHz", buzzer_msec, buzzer_freq);
        !            93:        y++;
        !            94: 
        !            95:        // マウスとの間を1行開ける
        !            96:        y++;
        !            97: 
        !            98:        mx = mouse_x;
        !            99:        my = mouse_y;
        !           100:        if (mx < -999)
        !           101:                mx = -999;
        !           102:        if (mx > 999)
        !           103:                mx = 999;
        !           104:        if (my < -999)
        !           105:                my = -999;
        !           106:        if (my > 999)
        !           107:                my = 999;
        !           108: 
        !           109:        screen.Puts(0, y, "Mouse:");
        !           110:        screen.Print(x,  y, "sampling=%s", mouse_on ? "on" : "off");
        !           111:        screen.Print(x + 13, y, (mouse_on ? TA::Normal : TA::Disable),
        !           112:                "x=%-4d y=%-4d", mx, my);
        !           113:        if (mouse_on) {
        !           114:                screen.Puts(x + 27, y, TA::OnOff(mouse_l), "L");
        !           115:                screen.Puts(x + 29, y, TA::OnOff(mouse_m), "M");
        !           116:                screen.Puts(x + 31, y, TA::OnOff(mouse_r), "R");
        !           117:        } else {
        !           118:                screen.Puts(x + 27, y, TA::Disable, "L M R");
        !           119:        }
1.1.1.2   root      120: }
                    121: 
1.1.1.12! root      122: // 共通 keystat を LUNA キーコードに変換して返す。
1.1.1.9   root      123: // 対応する LUNA のキーがなければ 0 を返す。
                    124: uint
1.1.1.12! root      125: LunaKeyboard::KeyToMDKey(uint keystat) const
1.1.1.4   root      126: {
1.1.1.12! root      127:        uint keycode = KC_CODE(keystat);
1.1.1.9   root      128:        if (keycode >= countof(keycode2lunakey_table)) {
1.1.1.4   root      129:                return 0;
                    130:        }
                    131: 
1.1.1.12! root      132:        uint mdkey = keycode2lunakey_table[keycode];
        !           133:        if (mdkey && KC_IS_BREAK(keystat)) {
        !           134:                mdkey |= 0x80;
        !           135:        }
        !           136:        return mdkey;
1.1       root      137: }
                    138: 
1.1.1.9   root      139: // シフト状態なら true を返す
                    140: bool
                    141: LunaKeyboard::IsShift() const
1.1       root      142: {
1.1.1.9   root      143:        return pressed[KC_SHIFT_L] || pressed[KC_SHIFT_R];
1.1.1.4   root      144: }
                    145: 
1.1.1.10  root      146: // キー入力を1つ処理する
                    147: void
                    148: LunaKeyboard::KeyInput(uint keystat)
1.1.1.4   root      149: {
1.1.1.10  root      150:        uint keycode = KC_CODE(keystat);
                    151:        bool ismake = KC_IS_MAKE(keystat);
                    152: 
                    153:        assert(keycode < KC_max);
                    154: 
1.1.1.12! root      155:        // LUNA キーボードの LED キーは、
        !           156:        // LED 消灯中の押下で Make、点灯中の押下で Break を送り、
        !           157:        // LED キーの開放は VM に対しては何もしない。Issue#83
        !           158:        //
        !           159:        // LED  ismake    keystat 送信コード
        !           160:        // ------------   -------------
        !           161:        // off  MAKE    : MAKE  MAKE    キー押下、Make  を入力 (LED を on)
        !           162:        // on   MAKE    : MAKE  BREAK   キー押下、Break を入力 (LED を off)
        !           163:        // off  BREAK   : BREAK none    キー開放
        !           164:        // on   BREAK   : BREAK none    キー開放
        !           165:        int n = Keycode2LED(keycode);
        !           166:        if (n >= 0) {
        !           167:                if (ismake) {
        !           168:                        keystat |= (led[n] ? KC_FLAG_LED_BREAK : KC_FLAG_LED_MAKE);
        !           169:                } else {
        !           170:                        // Break 時はキー入力はしない (キーの開放処理自体は必要)
        !           171:                        keystat |= KC_FLAG_LED_DROP;
        !           172:                }
        !           173:        }
        !           174: 
1.1.1.10  root      175:        // 共通処理へ
                    176:        if (KeyInputCommon(keystat) == false) {
                    177:                return;
                    178:        }
                    179: 
1.1.1.12! root      180:        // 処理できたらここで LED の状態を更新
        !           181:        if (n >= 0 && ismake) {
        !           182:                led[n] = !led[n];
        !           183: 
        !           184:                // LED 状態が変更になったので全走査指示。
        !           185:                // KeyInputCommon() 内で一度ポストしてるので無駄気味だが仕方ない…
        !           186:                UIMessage::Post(UIMessage::KEYBOARD);
1.1.1.9   root      187:        }
1.1       root      188: 
1.1.1.10  root      189:        // LUNA のキーボードはキーボード側でキーリピートしないので
                    190:        // ここでは何もしなくてよい
1.1.1.2   root      191: }
                    192: 
1.1.1.9   root      193: // 共通キーコードから LED 番号を返す。LED キーでなければ -1 を返す。
                    194: int
                    195: LunaKeyboard::Keycode2LED(uint keycode) const
1.1.1.2   root      196: {
1.1.1.9   root      197:        // 2つしかないのでこのくらいでいいか
                    198:        if (keycode == KC_kana)
                    199:                return 0;
                    200:        if (keycode == KC_CAPS)
                    201:                return 1;
1.1.1.2   root      202: 
1.1.1.9   root      203:        return -1;
1.1.1.2   root      204: }
                    205: 
1.1.1.12! root      206: // LED 番号から共通キーコードを返す。LED 番号が不正なら KC_none を返す。
        !           207: uint
        !           208: LunaKeyboard::LED2Keycode(int ledcode) const
        !           209: {
        !           210:        // 2つしかないのでこのくらいでいいか
        !           211:        if (ledcode == 0)
        !           212:                return KC_kana;
        !           213:        if (ledcode == 1)
        !           214:                return KC_CAPS;
        !           215: 
        !           216:        return KC_none;
        !           217: }
        !           218: 
1.1.1.2   root      219: // マウス入力
                    220: void
                    221: LunaKeyboard::MouseInput(int x, int y, bool rb, bool lb, bool mb)
                    222: {
                    223:        // ホストからマウスイベントのたびに呼ばれるので、ここで積算。
                    224:        // 20msec ごとのサンプリングのタイミングで積算結果を処理する。
                    225:        // LUNA のマウスの Y 方向は上に動く方向がプラスなので、ホスト入力とは逆。
1.1.1.12! root      226:        if (mouse_on) {
        !           227:                mouse_x += x;
        !           228:                mouse_y -= y;
        !           229:                mouse_r = rb;
        !           230:                mouse_l = lb;
        !           231:                mouse_m = mb;
        !           232:        }
1.1.1.2   root      233: }
                    234: 
1.1.1.12! root      235: // キー送信を開始 (Keyboard から呼ばれる)
1.1.1.9   root      236: void
                    237: LunaKeyboard::SendStart()
                    238: {
1.1.1.12! root      239:        // ここでは次の 2msec 単位にイベントコールバックを起動するだけ。
        !           240:        Start(2_msec);
        !           241: }
1.1.1.9   root      242: 
1.1.1.12! root      243: // イベントを次の period nsec 単位後に開始。
        !           244: void
        !           245: LunaKeyboard::Start(uint64 period)
        !           246: {
1.1.1.9   root      247:        uint64 now = gMPU->GetVirtTime();
1.1.1.12! root      248:        uint64 target = ((now / period) + 1) * period;
        !           249:        // XXX メンバの event.vtime 参照してるけどどうするかね
        !           250:        if (event.IsRunning() == false || target < event.vtime) {
        !           251:                event.time = target - now;
        !           252:                event.Start();
1.1.1.9   root      253:        }
                    254: }
                    255: 
1.1.1.12! root      256: // イベントコールバック。
        !           257: // キー入力、マウス入力、ブザー出力のいずれかが発生している間 2msec ごとに
        !           258: // 呼ばれる。
1.1.1.2   root      259: void
1.1.1.12! root      260: LunaKeyboard::Callback(Event& ev)
1.1.1.2   root      261: {
1.1.1.12! root      262:        uint64 now = gMPU->GetVirtTime();
        !           263:        uint mdkey;
1.1.1.6   root      264: 
1.1.1.12! root      265:        // マウスサンプリングオンなら 20msec ごとにサンプリングを行う。
        !           266:        if (mouse_on && (now / 2_msec) % 10 == 0) {
        !           267:                MouseSampling();
1.1.1.9   root      268:        }
                    269: 
1.1.1.12! root      270:        if (sendqueue.Dequeue(&mdkey)) {
        !           271:                // キューから取り出す。ここで取り出せるのは MDKey
        !           272:                // またはマウスデータ
        !           273:                // 送信
        !           274:                gSIO->Rx(1, mdkey);
        !           275:        }
1.1.1.4   root      276: 
1.1.1.12! root      277:        if (buzzer_on && now > buzzer_end) {
        !           278:                buzzer_on = false;
        !           279:                Release();
1.1.1.9   root      280:        }
                    281: 
1.1.1.12! root      282:        if (sendqueue.Empty() == false || buzzer_on) {
        !           283:                // 送信データが残っていれば次は 2msec 後
        !           284:                Start(2_msec);
        !           285:        } else if (mouse_on) {
        !           286:                // そうでなくて、マウスサンプリングがオンなら次の 20msec 単位後
        !           287:                Start(20_msec);
1.1.1.4   root      288:        }
1.1.1.2   root      289: }
                    290: 
1.1.1.12! root      291: // マウスサンプリング
1.1.1.2   root      292: void
1.1.1.12! root      293: LunaKeyboard::MouseSampling()
1.1.1.2   root      294: {
                    295:        // 移動量が±1 を超えるかボタンがどれかでも変化すれば送信。
1.1.1.11  root      296:        if (mouse_x < -1 || mouse_x > 1 ||
                    297:            mouse_y < -1 || mouse_y > 1 ||
1.1.1.2   root      298:            mouse_r != prev_r ||
                    299:            mouse_l != prev_l ||
                    300:            mouse_m != prev_m)
                    301:        {
1.1.1.12! root      302:                putlog(2, "Mouse Sampling x=%d y=%d %c%c%c",
        !           303:                        mouse_x, mouse_y,
        !           304:                        (mouse_l ? 'L' : '-'),
        !           305:                        (mouse_m ? 'M' : '-'),
        !           306:                        (mouse_r ? 'R' : '-'));
        !           307: 
        !           308:                // 1バイト目、ボタン状態。
        !           309:                // mouse_[lmr] 変数は押し下げが true、LUNA のマウスは押し下げが %0
        !           310:                uint8 b = 0x80 |
        !           311:                        (mouse_l ? 0 : 0x04) |
        !           312:                        (mouse_m ? 0 : 0x02) |
        !           313:                        (mouse_r ? 0 : 0x01);
        !           314: 
        !           315:                // 2バイト目が X、3バイト目が Y。
        !           316:                // 移動量は絶対値 0x7f でサチる (signed char ではない)。
        !           317:                if (mouse_x < -127)
        !           318:                        mouse_x = -127;
        !           319:                if (mouse_x > 127)
        !           320:                        mouse_x = 127;
        !           321: 
        !           322:                if (mouse_y < -127)
        !           323:                        mouse_y = -127;
        !           324:                if (mouse_y > 127)
        !           325:                        mouse_y = 127;
        !           326: 
        !           327:                // キューに入れておく
        !           328:                sendqueue.Enqueue(b);
        !           329:                sendqueue.Enqueue((uint8)mouse_x);
        !           330:                sendqueue.Enqueue((uint8)mouse_y);
        !           331: 
        !           332:                // 積算リセット
        !           333:                mouse_x = 0;
        !           334:                mouse_y = 0;
        !           335:                prev_r = mouse_r;
        !           336:                prev_l = mouse_l;
        !           337:                prev_m = mouse_m;
1.1.1.2   root      338:        }
1.1.1.11  root      339: }
                    340: 
1.1.1.12! root      341: // マウスサンプリングを ON にする
1.1.1.11  root      342: void
1.1.1.12! root      343: LunaKeyboard::MouseOn()
1.1.1.11  root      344: {
1.1.1.12! root      345:        // 厳密なタイミングは分からないので、
        !           346:        // 実装都合で次のマウススロットからサンプリングを開始(再開)する。
        !           347:        mouse_on = true;
1.1.1.2   root      348: 
1.1.1.12! root      349:        // 次の 20msec 単位後から開始
        !           350:        Start(20_msec);
        !           351: }
        !           352: 
        !           353: // マウスサンプリングを OFF にする
        !           354: void
        !           355: LunaKeyboard::MouseOff()
        !           356: {
        !           357:        mouse_on = false;
1.1.1.11  root      358:        mouse_x = 0;
                    359:        mouse_y = 0;
1.1.1.12! root      360:        mouse_r = false;
        !           361:        mouse_l = false;
        !           362:        mouse_m = false;
        !           363:        prev_r = false;
        !           364:        prev_l = false;
        !           365:        prev_m = false;
1.1.1.2   root      366: }
                    367: 
1.1.1.12! root      368: // ?
1.1.1.2   root      369: void
1.1.1.12! root      370: LunaKeyboard::MouseSendStart()
1.1.1.2   root      371: {
1.1       root      372: }
                    373: 
1.1.1.12! root      374: static const uint buzzer_msec_table[] = { 40, 150, 400, 700 };
        !           375: static const uint buzzer_freq_table[] = {
        !           376:        6000, 3000, 1500, 1000, 600, 300, 150, 100
        !           377: };
        !           378: 
1.1.1.4   root      379: // ホストからの制御
                    380: void
                    381: LunaKeyboard::Command(uint32 data)
                    382: {
1.1.1.12! root      383:        switch (data & 0xe0) {
        !           384:         case 0x00:     // LED 点灯コマンド
        !           385:         {
        !           386:                //   7   6   5   4   3   2   1   0
        !           387:                // +---+---+---+---+---+---+---+---+
        !           388:                // | 0   0   0 |LED| x   x   x |COD|
        !           389:                // +---+---+---+---+---+---+---+---+
        !           390:                //               |               +--- 0:かな 1:CAP
        !           391:                //               +------------------- 0:消灯 1:点灯
        !           392:                uint code = data & 0x01;
        !           393:                uint on   = data & 0x10;
        !           394:                led[code] = (bool)on;
        !           395:                UIMessage::Post(UIMessage::KEYBOARD);
        !           396:                if (loglevel >= 1) {
        !           397:                        const auto name = GetKeyName(LED2Keycode(code));
        !           398:                        putlogn("Command LED $%x(%s) %s",
        !           399:                                code, name.c_str(), (on ? "ON" : "OFF"));
        !           400:                }
        !           401:                break;
        !           402:         }
1.1.1.4   root      403: 
1.1.1.12! root      404:         case 0x40:     // ブザーコマンド
        !           405:         {
        !           406:                //   7   6   5   4   3   2   1   0
        !           407:                // +---+---+---+---+---+---+---+---+
        !           408:                // | 0   1   0 |T2  T1 |F3  F2  F1 |
        !           409:                // +---+---+---+---+---+---+---+---+
        !           410:                //                 |         +------- 周波数
        !           411:                //                 +----------------- 時間
        !           412:                uint t = (data >> 3) & 3;
        !           413:                uint f = data & 7;
        !           414:                buzzer_msec = buzzer_msec_table[t];
        !           415:                buzzer_freq = buzzer_freq_table[f];
        !           416:                putlog(1, "Command Buzzer %dmsec, %dHz", buzzer_msec, buzzer_freq);
        !           417: 
        !           418:                uint64 now = gMPU->GetVirtTime();
        !           419:                buzzer_end = now + buzzer_msec * 1_msec;
        !           420:                buzzer_on = true;
        !           421:                Acquire();
        !           422:                Start(2_msec);
        !           423:                break;
        !           424:         }
        !           425: 
        !           426:         case 0x20:     // マウス OFF コマンド
        !           427:                //   7   6   5   4   3   2   1   0
        !           428:                // +---+---+---+---+---+---+---+---+
        !           429:                // | 0   0   1 | x   x   x   x   x |
        !           430:                // +---+---+---+---+---+---+---+---+
        !           431:                putlog(1, "Command Mouse Sampling Off");
        !           432:                MouseOff();
        !           433:                break;
        !           434: 
        !           435:         case 0x60:     // マウス ON コマンド
        !           436:                //   7   6   5   4   3   2   1   0
        !           437:                // +---+---+---+---+---+---+---+---+
        !           438:                // | 0   1   1 | x   x   x   x   x |
        !           439:                // +---+---+---+---+---+---+---+---+
        !           440:                putlog(1, "Command Mouse Sampling On");
        !           441:                MouseOn();
        !           442:                break;
        !           443: 
        !           444:         default:
        !           445:                putlog(1, "未定義コマンド受信 $%02x", data);
        !           446:                break;
        !           447:        }
        !           448: }
1.1       root      449: 
                    450: // キーコード変換表
                    451: // 共通キーコードから LUNA キーコードに変換する。
                    452: // ぶっちゃけた話共通キーコードは LUNA キーコードをベースにしているので、
                    453: // 穴がある以外は全部透過。
                    454: /*static*/ const uint
1.1.1.12! root      455: LunaKeyboard::keycode2lunakey_table[KC_max] = {
1.1       root      456:        NoKey,                                  // [00]
                    457:        NoKey,                                  // [01]
                    458:        NoKey,                                  // [02]
                    459:        NoKey,                                  // [03]
                    460:        NoKey,                                  // [04]
                    461:        NoKey,                                  // [05]
                    462:        NoKey,                                  // [06]
                    463:        NoKey,                                  // [07]
                    464:        NoKey,                                  // [08]
                    465:        LunaKey_TAB,                    // [09]
                    466:        LunaKey_CTRL,                   // [0a]
                    467:        LunaKey_kana,                   // [0b]
                    468:        LunaKey_SHIFT_L,                // [0c]
                    469:        LunaKey_SHIFT_R,                // [0d]
                    470:        LunaKey_CAPS,                   // [0e]
                    471:        LunaKey_SF,                             // [0f]
                    472: 
                    473:        LunaKey_ESC,                    // [10]
                    474:        LunaKey_BS,                             // [11]
                    475:        LunaKey_enter,                  // [12]
                    476:        NoKey,                                  // [13]
                    477:        LunaKey_space,                  // [14]
                    478:        LunaKey_DEL,                    // [15]
                    479:        LunaKey_XFER,                   // [16]
                    480:        LunaKey_VALID,                  // [17]
                    481:        LunaKey_PF11,                   // [18]
                    482:        LunaKey_PF12,                   // [19]
                    483:        LunaKey_PF13,                   // [1a]
                    484:        LunaKey_PF14,                   // [1b]
                    485:        LunaKey_up,                             // [1c]
                    486:        LunaKey_left,                   // [1d]
                    487:        LunaKey_right,                  // [1e]
                    488:        LunaKey_down,                   // [1f]
                    489: 
                    490:        NoKey,                                  // [20]
                    491:        NoKey,                                  // [21]
                    492:        LunaKey_1,                              // [22]
                    493:        LunaKey_2,                              // [23]
                    494:        LunaKey_3,                              // [24]
                    495:        LunaKey_4,                              // [25]
                    496:        LunaKey_5,                              // [26]
                    497:        LunaKey_6,                              // [27]
                    498:        LunaKey_7,                              // [28]
                    499:        LunaKey_8,                              // [29]
                    500:        LunaKey_9,                              // [2a]
                    501:        LunaKey_0,                              // [2b]
                    502:        LunaKey_minus,                  // [2c]
                    503:        LunaKey_circum,                 // [2d]
                    504:        LunaKey_backslash,              // [2e]
                    505:        NoKey,                                  // [2f]
                    506: 
                    507:        NoKey,                                  // [30]
                    508:        NoKey,                                  // [31]
                    509:        LunaKey_Q,                              // [32]
                    510:        LunaKey_W,                              // [33]
                    511:        LunaKey_E,                              // [34]
                    512:        LunaKey_R,                              // [35]
                    513:        LunaKey_T,                              // [36]
                    514:        LunaKey_Y,                              // [37]
                    515:        LunaKey_U,                              // [38]
                    516:        LunaKey_I,                              // [39]
                    517:        LunaKey_O,                              // [3a]
                    518:        LunaKey_P,                              // [3b]
                    519:        LunaKey_at,                             // [3c]
                    520:        LunaKey_bracketleft,    // [3d]
                    521:        NoKey,                                  // [3e]
                    522:        NoKey,                                  // [3f]
                    523: 
                    524:        NoKey,                                  // [40]
                    525:        NoKey,                                  // [41]
                    526:        LunaKey_A,                              // [42]
                    527:        LunaKey_S,                              // [43]
                    528:        LunaKey_D,                              // [44]
                    529:        LunaKey_F,                              // [45]
                    530:        LunaKey_G,                              // [46]
                    531:        LunaKey_H,                              // [47]
                    532:        LunaKey_J,                              // [48]
                    533:        LunaKey_K,                              // [49]
                    534:        LunaKey_L,                              // [4a]
                    535:        LunaKey_semicolon,              // [4b]
                    536:        LunaKey_colon,                  // [4c]
                    537:        LunaKey_bracketright,   // [4d]
                    538:        NoKey,                                  // [4e]
                    539:        NoKey,                                  // [4f]
                    540: 
                    541:        NoKey,                                  // [50]
                    542:        NoKey,                                  // [51]
                    543:        LunaKey_Z,                              // [52]
                    544:        LunaKey_X,                              // [53]
                    545:        LunaKey_C,                              // [54]
                    546:        LunaKey_V,                              // [55]
                    547:        LunaKey_B,                              // [56]
                    548:        LunaKey_N,                              // [57]
                    549:        LunaKey_M,                              // [58]
                    550:        LunaKey_comma,                  // [59]
                    551:        LunaKey_period,                 // [5a]
                    552:        LunaKey_slash,                  // [5b]
                    553:        LunaKey_underscore,             // [5c]
                    554:        NoKey,                                  // [5d]
                    555:        NoKey,                                  // [5e]
                    556:        NoKey,                                  // [5f]
                    557: 
                    558:        NoKey,                                  // [60]
                    559:        LunaKey_PAD_plus,               // [61]
                    560:        LunaKey_PAD_minus,              // [62]
                    561:        LunaKey_PAD_7,                  // [63]
                    562:        LunaKey_PAD_8,                  // [64]
                    563:        LunaKey_PAD_9,                  // [65]
                    564:        LunaKey_PAD_4,                  // [66]
                    565:        LunaKey_PAD_5,                  // [67]
                    566:        LunaKey_PAD_6,                  // [68]
                    567:        LunaKey_PAD_1,                  // [69]
                    568:        LunaKey_PAD_2,                  // [6a]
                    569:        LunaKey_PAD_3,                  // [6b]
                    570:        LunaKey_PAD_0,                  // [6c]
                    571:        LunaKey_PAD_decimal,    // [6d]
                    572:        LunaKey_PAD_enter,              // [6e]
                    573:        NoKey,                                  // [6f]
                    574: 
                    575:        NoKey,                                  // [70]
                    576:        NoKey,                                  // [71]
                    577:        LunaKey_F1,                             // [72]
                    578:        LunaKey_F2,                             // [73]
                    579:        LunaKey_F3,                             // [74]
                    580:        LunaKey_F4,                             // [75]
                    581:        LunaKey_F5,                             // [76]
                    582:        LunaKey_F6,                             // [77]
                    583:        LunaKey_F7,                             // [78]
                    584:        LunaKey_F8,                             // [79]
                    585:        LunaKey_F9,                             // [7a]
                    586:        LunaKey_F10,                    // [7b]
                    587:        LunaKey_PAD_multiply,   // [7c]
                    588:        LunaKey_PAD_divide,             // [7d]
                    589:        LunaKey_PAD_equal,              // [7e]
                    590:        LunaKey_PAD_comma,              // [7f]
                    591: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.