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

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

unix.superglobalmegacorp.com

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