Annotation of nono/vm/x68kkbd.cpp, revision 1.1.1.19

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.10  root        7: //
                      8: // X68k キーボード
                      9: //
                     10: 
1.1.1.5   root       11: // 送信タイミングについて
                     12: //     キーボードは MFP の USART に繋がっている。
                     13: //     MFP USART の RR 線 (Receiver Ready) は受信可能なら 'H'、受信中は 'L' に
                     14: //     なっている。キーボードは RR が 'H' の時だけデータを送信する。また、
                     15: //     システムポート#4 の KEY CTRL = 0 (キーデータ送信不可) はこの RR を
                     16: //     'L' に落とす AND 回路になっている。キーボードからの送信は 2400bps、
                     17: //     ストップビット1、パリティなしなので、1バイトの送信に 3.75 msec かかる。
                     18: //     実装では、キーボードは MFP の RR が 'H' なら MFP にキーデータを送信。
                     19: //     MFP 側で RR を 'L' にして 3.75 msec をイベントで待った後、キーを処理
                     20: //     して RR を 'H' に戻すことにする。
                     21: 
                     22: // SHIFT キーについては keyboard.cpp のコメントを参照。
1.1.1.4   root       23: 
1.1       root       24: #include "x68kkbd.h"
1.1.1.19! root       25: #include "event.h"
1.1       root       26: #include "mfp.h"
1.1.1.16  root       27: #include "monitor.h"
1.1.1.7   root       28: #include "scc.h"
1.1.1.10  root       29: #include "scheduler.h"
1.1.1.5   root       30: #include "sysport.h"
1.1.1.18  root       31: #include "uimessage.h"
1.1       root       32: 
                     33: // コンストラクタ
                     34: X68030Keyboard::X68030Keyboard()
                     35: {
1.1.1.4   root       36:        led.resize(7);
1.1.1.6   root       37: 
1.1.1.16  root       38:        monitor = gMonitorManager->Regist(ID_MONITOR_KEYBOARD, this);
                     39:        monitor->func = ToMonitorCallback(&X68030Keyboard::MonitorUpdate);
                     40:        monitor->SetSize(47, 5);
1.1.1.3   root       41: }
                     42: 
                     43: // デストラクタ
                     44: X68030Keyboard::~X68030Keyboard()
                     45: {
                     46: }
                     47: 
1.1.1.12  root       48: // 初期化
                     49: bool
                     50: X68030Keyboard::Init()
                     51: {
                     52:        if (inherited::Init() == false) {
                     53:                return false;
                     54:        }
                     55: 
                     56:        mfp = GetMFPDevice();
                     57:        scc = GetSCCDevice();
                     58:        sysport = GetSysportDevice();
                     59: 
1.1.1.19! root       60:        auto evman = GetEventManager();
        !            61:        rept_event = evman->Regist(this,
        !            62:                ToEventCallback(&X68030Keyboard::ReptCallback),
        !            63:                "Keyboard Repeat");
        !            64: 
        !            65:        mouse_event = evman->Regist(this,
        !            66:                ToEventCallback(&X68030Keyboard::MouseCallback),
        !            67:                "Mouse");
1.1.1.15  root       68: 
1.1.1.12  root       69:        return true;
                     70: }
                     71: 
1.1.1.10  root       72: // キーボード接続時の MD 固有処理
1.1.1.4   root       73: void
1.1.1.10  root       74: X68030Keyboard::MDConnect()
1.1.1.3   root       75: {
1.1.1.11  root       76:        rept_delay_data = 3;
1.1.1.6   root       77:        rept_delay = 500_msec;
1.1.1.11  root       78:        rept_time_data = 4;
1.1.1.6   root       79:        rept_time  = 110_msec;
                     80:        rept_key = KC_none;
1.1.1.12  root       81:        scheduler->StopEvent(rept_event);
1.1.1.4   root       82: 
                     83:        led_darkness = 0;
1.1.1.7   root       84: 
1.1.1.10  root       85:        // XXX マウスの接続取り外しは未定
1.1.1.12  root       86:        scheduler->StopEvent(mouse_event);
1.1.1.19! root       87:        mouse_event->code = 0;
1.1.1.10  root       88: }
                     89: 
                     90: // キーボード取り外し時の MD 固有処理
                     91: void
                     92: X68030Keyboard::MDDisconnect()
                     93: {
1.1.1.12  root       94:        scheduler->StopEvent(rept_event);
                     95:        scheduler->StopEvent(mouse_event);
1.1.1.19! root       96:        mouse_event->code = 0;
1.1       root       97: }
                     98: 
1.1.1.11  root       99: // モニター
                    100: void
                    101: X68030Keyboard::MonitorUpdate(Monitor *, TextScreen& screen)
                    102: {
                    103:        int y;
                    104: 
                    105:        screen.Clear();
                    106:        y = 0;
                    107: 
                    108:        // 0         1         2         3         4
                    109:        // 01234567890123456789012345678901234567890123456
                    110:        // Key Enable:     %             MSCTRL:         %
                    111:        // Ctrl Enable:                  OPT.2 Enable:   %
                    112:        // Key Repeat: Delay  $x(????msec)
                    113:        //             Repeat $x(????msec)
1.1.1.13  root      114:        // LED: $xx    Zen  Hira INS  CAPS Code Roma Kana
1.1.1.11  root      115:        // LED Darkness: x
                    116: 
                    117:        // KEY_EN, CTRL_EN, OPT2_EN, MSCTRL は未実装
                    118: 
                    119:        // キーリピート
                    120:        screen.Puts(0, y, "Key Repeat:");
1.1.1.15  root      121:        screen.Print(12, y++, "Delay  $%x(%4umsec)",
                    122:                rept_delay_data, (uint)(rept_delay / 1_msec));
                    123:        screen.Print(12, y++, "Repeat $%x(%4umsec)",
                    124:                rept_time_data, (uint)(rept_time / 1_msec));
1.1.1.11  root      125: 
                    126:        // マウス
                    127:        int mx = mouse_x;
                    128:        int my = mouse_y;
                    129:        if (mx < -999)
                    130:                mx = -999;
                    131:        if (mx > 999)
                    132:                mx = 999;
                    133:        if (my < -999)
                    134:                my = -999;
                    135:        if (my > 999)
                    136:                my = 999;
                    137: 
                    138:        screen.Puts(0, y, "Mouse:");
                    139:        screen.Print(12, y, "x=%-4d y=%-4d", mx, my);
                    140:        screen.Print(27, y, TA::OnOff(mouse_l), "L");
                    141:        screen.Print(29, y, TA::OnOff(mouse_r), "R");
                    142:        y++;
                    143: 
                    144:        // LED
                    145:        screen.Puts(0, y, "LED:");
                    146:        static const char * const ledname[] = {
                    147:                "Zen",  "Hira", "INS",  "CAPS", "Code", "Roma", "Kana"
                    148:        };
                    149:        uint val = 0x80;
                    150:        for (int i = 0; i < 7; i++) {
                    151:                int n = 6 - i;
1.1.1.13  root      152:                screen.Puts(12 + i * 5, y, TA::OnOff(led[n]), ledname[i]);
1.1.1.11  root      153:                if (led[n] == 0) {
1.1.1.19! root      154:                        val |= 1U << n;
1.1.1.11  root      155:                }
                    156:        }
1.1.1.13  root      157:        screen.Print(5, y, "$%02x", val);
1.1.1.11  root      158:        y++;
                    159: 
                    160:        // LED の明るさ (というより暗さ)
1.1.1.15  root      161:        screen.Print(0, y++, "LED Darkness: %u", led_darkness);
1.1.1.11  root      162: }
                    163: 
1.1.1.9   root      164: // 共通 keystat を X680x0 キーコードに変換して返す。
1.1.1.5   root      165: // 対応する X680x0 のキーがなければ 0 を返す。
                    166: uint
1.1.1.9   root      167: X68030Keyboard::KeyToMDKey(uint keystat) const
1.1       root      168: {
1.1.1.9   root      169:        uint keycode = KC_CODE(keystat);
1.1.1.5   root      170:        if (keycode >= countof(keycode2x68kkey_table)) {
                    171:                return 0;
                    172:        }
1.1       root      173: 
1.1.1.9   root      174:        uint mdkey = keycode2x68kkey_table[keycode];
                    175:        if (mdkey && KC_IS_BREAK(keystat)) {
                    176:                mdkey |= 0x80;
                    177:        }
                    178:        return mdkey;
1.1.1.5   root      179: }
                    180: 
                    181: // シフト状態なら true を返す
                    182: bool
                    183: X68030Keyboard::IsShift() const
                    184: {
                    185:        return pressed[KC_SHIFT];
                    186: }
1.1       root      187: 
1.1.1.6   root      188: // キー入力を1つ処理する
                    189: void
                    190: X68030Keyboard::KeyInput(uint keystat)
1.1.1.5   root      191: {
1.1.1.6   root      192:        uint keycode = KC_CODE(keystat);
                    193:        bool ismake = KC_IS_MAKE(keystat);
                    194: 
                    195:        assert(keycode < KC_max);
                    196: 
1.1.1.5   root      197:        // X68k のキーボードは左右の [SHIFT] の区別がない。
                    198:        // KC_SHIFT_L はホストの物理キー左 [SHIFT] に対応、
                    199:        // KC_SHIFT_R はホストの物理キー右 [SHIFT] に対応、
                    200:        // KC_SHIFT はソフトウェアキーボードからの左右のない [SHIFT] に対応。
                    201:        // どのキーコードで問い合わせをされても KC_SHIFT_L と KC_SHIFT_R の OR が
                    202:        // [SHIFT] キーの状態である。
                    203:        if (keycode == KC_SHIFT_L || keycode == KC_SHIFT_R) {
1.1.1.17  root      204:                // それぞれのシフトキーが押されたことは覚えておく。
                    205:                SetPressed(keycode, ismake);
                    206:                // 反対側のキーが押されていたら、いま押した・離したほうは無視する
                    207:                if (IsPressed(keycode ^ 1)) {
1.1.1.6   root      208:                        return;
1.1.1.5   root      209:                }
1.1.1.6   root      210:                keycode = KC_SHIFT;
1.1.1.8   root      211: 
1.1.1.6   root      212:                // keycode を変更したので keystat も更新
1.1.1.8   root      213:                keystat = (keystat & 0xff00) | keycode;
1.1       root      214:        }
1.1.1.5   root      215: 
1.1.1.6   root      216:        // 共通処理へ
                    217:        if (KeyInputCommon(keystat) == false) {
                    218:                return;
                    219:        }
1.1       root      220: 
1.1.1.4   root      221:        // LED は MPU 側から点灯/消灯指示が来るのでここでは何もしなくてよい
1.1       root      222: 
1.1.1.6   root      223:        // ここでキーリピートのイベント開始処理
                    224:        if (ismake) {
                    225:                // いま起きているリピートは中止
                    226:                rept_key = keycode;
1.1.1.19! root      227:                rept_event->time = rept_delay;
1.1.1.12  root      228:                scheduler->RestartEvent(rept_event);
1.1.1.6   root      229:        } else {
                    230:                if (keycode == rept_key) {
                    231:                        // 同じキーのブレークでのみリピートを終了する
1.1.1.12  root      232:                        scheduler->StopEvent(rept_event);
1.1.1.6   root      233:                        rept_key = KC_none;
                    234:                }
                    235:        }
                    236: }
1.1.1.5   root      237: 
1.1.1.6   root      238: void
1.1.1.19! root      239: X68030Keyboard::ReptCallback(Event *ev)
1.1.1.6   root      240: {
                    241:        // リピート
1.1.1.9   root      242:        sendqueue.Enqueue(KeyToMDKey(rept_key));
1.1.1.6   root      243:        SendStart();
                    244: 
                    245:        // 二回目以降のリピートは rept_time 間隔で発生
1.1.1.19! root      246:        rept_event->time = rept_time;
1.1.1.12  root      247:        scheduler->StartEvent(rept_event);
1.1       root      248: }
1.1.1.5   root      249: 
                    250: // MFP、システムポートと、キーボードの関係。
                    251: //
                    252: // キーボードの Ready 信号は MFP の RR とシステムポートの KeyCtrl の
                    253: // AND で作られているが、この AND 部分はキーボードが担当することにする。
                    254: // そのほうが都合がいいため。
                    255: //
                    256: //                 <- 本体 || キーボード ->
                    257: //   MFP                   ||
                    258: // --------+     :         ||  +-----
1.1.1.10  root      259: //         |     :  |&     ||  |
                    260: //       RR|o-------|&     ||  |
                    261: // --------+     :  |&---------|T0 (Ready)
                    262: //            +-----|&     ||  |
                    263: //  Sysport   |  :  |&     ||  |
1.1.1.5   root      264: // --------+  |  :         ||  |
                    265: //  KeyCtrl|--+  :         ||  +-----
                    266: //         |     :         ||
                    267: //               :エミュレータでは点線から右をキーボードが担当
1.1       root      268: 
1.1.1.5   root      269: // キーデータを送信
1.1       root      270: void
1.1.1.5   root      271: X68030Keyboard::SendStart()
1.1       root      272: {
1.1.1.12  root      273:        if (mfp->RxIsReady()) {
1.1.1.5   root      274:                // 本体が Ready ならここで送信
                    275:                Ready();
                    276:        } else {
                    277:                // そうでない場合、ここでは処理は不要。
                    278:                // MFP 側が受信可能になると Ready() がコールされ、そっちで処理される
1.1       root      279:        }
                    280: }
                    281: 
1.1.1.5   root      282: // MFP からの Ready 通知
                    283: // 実際にはキーボード側が MFP (を含む本体側) が Ready になるのを待っている
                    284: // のだが、待っているを作るのは大変なので。
1.1.1.2   root      285: void
1.1.1.5   root      286: X68030Keyboard::Ready()
1.1.1.2   root      287: {
1.1.1.12  root      288:        if (sysport->GetKeyCtrl()) {
1.1.1.5   root      289:                // KEYCTRL が有効なら処理する
                    290: 
1.1.1.9   root      291:                // ここで取り出せるのは MDKey。
                    292:                uint x68kkey;
                    293:                if (sendqueue.Dequeue(&x68kkey)) {
1.1.1.5   root      294:                        // あれば送信
                    295: 
                    296:                        // 呼ばれたからには送信できるはず
1.1.1.12  root      297:                        assert(mfp->RxIsReady() == true);
1.1.1.5   root      298: 
                    299:                        assert(x68kkey != 0);
                    300: 
                    301:                        // 送信
1.1.1.12  root      302:                        mfp->Rx(x68kkey);
1.1.1.5   root      303:                } else {
                    304:                        // なければ何もせず終了
                    305:                }
                    306:        } else {
                    307:                // KEYCTRL が無効なら何もしないだけでなく、キューをクリア。
                    308:                // KEYCTRL が無効から有効になった時に、無効だった期間のキーデータを
                    309:                // 吐き出すのはおかしいので。
                    310:                sendqueue.Clear();
                    311:        }
1.1.1.2   root      312: }
                    313: 
1.1.1.5   root      314: // マウス入力
1.1.1.4   root      315: void
1.1.1.5   root      316: X68030Keyboard::MouseInput(int x, int y, bool rb, bool lb, bool mb)
1.1.1.4   root      317: {
1.1.1.7   root      318:        // ホストからマウスイベントのたびに呼ばれるので、ここで積算。
                    319:        // 20msec ごとのサンプリングのタイミングで積算結果を処理する。
                    320:        // X68k のマウスの Y 方向は下に動く方向がプラス。
                    321:        mouse_x += x;
                    322:        mouse_y += y;
                    323:        mouse_r = rb;
                    324:        mouse_l = lb;
                    325: }
                    326: 
                    327: // マウスデータを VM に送信
                    328: void
                    329: X68030Keyboard::MouseSendStart()
                    330: {
                    331:        uint8 status = 0;
                    332: 
1.1.1.10  root      333:        // 最後のバイトを送るまでは、次は受け付けられない。
1.1.1.19! root      334:        // 送信中かどうかは mouse_event->code で判断している。
        !           335:        if (mouse_event->code != 0) {
1.1.1.7   root      336:                return;
                    337:        }
                    338: 
                    339:        if (mouse_x > 127) {
                    340:                status |= XOVFL;
                    341:                mouse_x = 127;
                    342:        }
                    343:        if (mouse_x < -128) {
                    344:                status |= XUNFL;
                    345:                mouse_x = -128;
                    346:        }
                    347:        if (mouse_y > 127) {
                    348:                status |= YOVFL;
                    349:                mouse_y = 127;
                    350:        }
                    351:        if (mouse_y < -128) {
                    352:                status |= YUNFL;
                    353:                mouse_y = -128;
                    354:        }
                    355:        status |= mouse_l ? SW_L : 0;
                    356:        status |= mouse_r ? SW_R : 0;
                    357: 
1.1.1.10  root      358:        // この時点でラッチしてみる(?)
                    359:        mouse_data[0] = status;
                    360:        mouse_data[1] = mouse_x;
                    361:        mouse_data[2] = mouse_y;
1.1.1.7   root      362: 
                    363:        mouse_x = 0;
                    364:        mouse_y = 0;
                    365: 
1.1.1.10  root      366:        // 1バイト目は MSCTRL が立ち下がってから 700us 以上後から送信。
1.1.1.14  root      367:        // さらに1バイトの送信に 2.3msec かかる(このすぐ下参照)。
1.1.1.19! root      368:        mouse_event->time = 700_usec + 2300_usec;
        !           369:        mouse_event->code = 1;
1.1.1.12  root      370:        scheduler->RestartEvent(mouse_event);
1.1.1.7   root      371: }
                    372: 
1.1.1.10  root      373: // マウスデータのイベントコールバック
1.1.1.7   root      374: void
1.1.1.19! root      375: X68030Keyboard::MouseCallback(Event *ev)
1.1.1.7   root      376: {
1.1.1.10  root      377:        // マウスは 4800bps で、ストップビット 2 なので11ビット。
                    378:        // 1/4800 * 11 = 2.29166 msec なので、1バイトあたり 2.3 msec にしておく。
                    379: 
1.1.1.14  root      380:        // code 1 なら1バイト目 (mouse_data[0]) の送信完了時刻が来た。
                    381:        // code 2 なら2バイト目 (mouse_data[1]) の送信完了時刻が来た。
                    382:        // code 3 なら3バイト目 (mouse_data[2]) の送信完了時刻が来た。
                    383:        // 3バイト目を送信してイベントループ終了。
1.1.1.10  root      384: 
1.1.1.19! root      385:        scc->Rx(1, mouse_data[mouse_event->code - 1]);
1.1.1.14  root      386: 
1.1.1.19! root      387:        if (mouse_event->code < 3) {
1.1.1.10  root      388:                // 次のイベント
1.1.1.19! root      389:                mouse_event->time = 2300_usec;
        !           390:                mouse_event->code++;
1.1.1.12  root      391:                scheduler->StartEvent(mouse_event);
1.1.1.10  root      392:        } else {
1.1.1.14  root      393:                // 3 バイト目の送信が終わった。
1.1.1.19! root      394:                mouse_event->code = 0;
1.1.1.10  root      395:        }
1.1.1.4   root      396: }
                    397: 
                    398: // ホストからの制御
                    399: void
                    400: X68030Keyboard::Command(uint32 data)
                    401: {
                    402:        if (data < 0x40) {
                    403:                // $00-$3f TV 制御
                    404:                // (実装不要)
1.1.1.11  root      405:                putlog(2, "Command TV control $%02x", (data & 0x1f));
1.1.1.4   root      406: 
                    407:        } else if (data < 0x48) {
                    408:                // $40-$47 MSCTRL 信号制御
                    409:                // こいつは頻度が高いのでログレベルを上げておく
1.1.1.15  root      410:                putlog(3, "Command MSCTRL control %u", (data & 1));
1.1.1.4   root      411: 
                    412:        } else if (data < 0x50) {
                    413:                // $48-$4f キーデータ送出許可
1.1.1.15  root      414:                putlog(1, "Command Key send enable %u (NOT IMPLEMENTED)", (data & 1));
1.1.1.4   root      415: 
                    416:        } else if (data < 0x54) {
                    417:                // $50-$53 ディスプレイ制御モード選択
                    418:                // (実装不要)
1.1.1.15  root      419:                putlog(2, "Command Display control mode %u", (data & 1));
1.1.1.4   root      420: 
                    421:        } else if (data < 0x58) {
                    422:                // $54-$57 LED 明るさ選択
                    423:                // 0 が明るく 3 が暗いので、明るさというより暗さ。
                    424:                led_darkness = (data & 3);
1.1.1.15  root      425:                putlog(1, "Command LED brightness %u", led_darkness);
1.1.1.19! root      426:                uimessage->Post(UIMessage::KEYBOARD);
1.1.1.4   root      427: 
                    428:        } else if (data < 0x5c) {
                    429:                // $58-$5b 本体からのディスプレイ制御許可
                    430:                // (実装不要)
1.1.1.15  root      431:                putlog(2, "Command Display control enable %u", (data & 1));
1.1.1.4   root      432: 
                    433:        } else if (data < 0x60) {
                    434:                // $5c-$5f OPT.2 によるディスプレイ制御許可
                    435:                // (実装不要)
1.1.1.15  root      436:                putlog(2, "Command OPT2 control enable %u", (data & 1));
1.1.1.4   root      437: 
                    438:        } else if (data < 0x70) {
                    439:                // $60-$6f リピートまでの時間
1.1.1.11  root      440:                rept_delay_data = data & 15;
                    441:                rept_delay = 200_msec + rept_delay_data * 100_msec;
1.1.1.15  root      442:                putlog(1, "Command Repeat Delay %u (%u msec)", rept_delay_data,
                    443:                        (uint)(rept_delay / 1_msec));
1.1.1.4   root      444: 
                    445:        } else if (data < 0x80) {
                    446:                // $70-$7f リピート間隔
1.1.1.11  root      447:                rept_time_data = data & 15;
                    448:                rept_time = 30_msec + rept_time_data * rept_time_data * 5_msec;
1.1.1.15  root      449:                putlog(1, "Command Repeat time  %d (%u msec)", rept_time_data,
                    450:                        (uint)(rept_time / 1_msec));
1.1.1.4   root      451: 
                    452:        } else {
                    453:                // $80-$ff LED 制御
                    454:                data &= 0x7f;
1.1.1.11  root      455:                putlog(1, "Command LED control $%02x", data);
1.1.1.4   root      456:                uint32 b = 0x01;
                    457:                for (int i = 0; i < led.size(); i++) {
                    458:                        // data は %0 で点灯、led[] は true で点灯
                    459:                        led[i] = ((data & b) == 0);
                    460:                        b <<= 1;
                    461:                }
1.1.1.19! root      462:                uimessage->Post(UIMessage::KEYBOARD);
1.1.1.4   root      463:        }
                    464: }
                    465: 
1.1       root      466: // キーコード変換表
                    467: // 共通キーコードから X680x0 キーコードに変換する。
                    468: /*static*/ const uint
1.1.1.5   root      469: X68030Keyboard::keycode2x68kkey_table[KC_max] = {
1.1       root      470:        NoKey,                                  // [00]
                    471:        X68kKey_BREAK,                  // [01]
1.1.1.19! root      472:        NoKey,                                  // [02]
1.1       root      473:        X68kKey_romaji,                 // [03]
1.1.1.4   root      474:        X68kKey_code,                   // [04]
1.1       root      475:        X68kKey_kigou,                  // [05]
                    476:        X68kKey_touroku,                // [06]
                    477:        X68kKey_HELP,                   // [07]
1.1.1.9   root      478:        X68kKey_SHIFT,                  // [08]
1.1       root      479:        X68kKey_TAB,                    // [09]
                    480:        X68kKey_CTRL,                   // [0a]
                    481:        X68kKey_kana,                   // [0b]
                    482:        X68kKey_SHIFT,                  // [0c]
1.1.1.5   root      483:        X68kKey_SHIFT,                  // [0d]
1.1       root      484:        X68kKey_CAPS,                   // [0e]
                    485:        NoKey,                                  // [0f]
                    486: 
                    487:        X68kKey_ESC,                    // [10]
                    488:        X68kKey_BS,                             // [11]
                    489:        X68kKey_enter,                  // [12]
1.1.1.19! root      490:        NoKey,                                  // [13]
1.1       root      491:        X68kKey_space,                  // [14]
                    492:        X68kKey_DEL,                    // [15]
                    493:        NoKey,                                  // [16]
                    494:        NoKey,                                  // [17]
                    495:        NoKey,                                  // [18]
                    496:        NoKey,                                  // [19]
                    497:        NoKey,                                  // [1a]
                    498:        NoKey,                                  // [1b]
                    499:        X68kKey_up,                             // [1c]
                    500:        X68kKey_left,                   // [1d]
                    501:        X68kKey_right,                  // [1e]
                    502:        X68kKey_down,                   // [1f]
                    503: 
1.1.1.19! root      504:        X68kKey_INS,                    // [20]
        !           505:        X68kKey_COPY,                   // [21]
1.1       root      506:        X68kKey_1,                              // [22]
                    507:        X68kKey_2,                              // [23]
                    508:        X68kKey_3,                              // [24]
                    509:        X68kKey_4,                              // [25]
                    510:        X68kKey_5,                              // [26]
                    511:        X68kKey_6,                              // [27]
                    512:        X68kKey_7,                              // [28]
                    513:        X68kKey_8,                              // [29]
                    514:        X68kKey_9,                              // [2a]
                    515:        X68kKey_0,                              // [2b]
                    516:        X68kKey_minus,                  // [2c]
                    517:        X68kKey_circum,                 // [2d]
                    518:        X68kKey_backslash,              // [2e]
1.1.1.9   root      519:        NoKey,                                  // [2f]
1.1       root      520: 
1.1.1.19! root      521:        NoKey,                                  // [30]
        !           522:        NoKey,                                  // [31]
1.1       root      523:        X68kKey_Q,                              // [32]
                    524:        X68kKey_W,                              // [33]
                    525:        X68kKey_E,                              // [34]
                    526:        X68kKey_R,                              // [35]
                    527:        X68kKey_T,                              // [36]
                    528:        X68kKey_Y,                              // [37]
                    529:        X68kKey_U,                              // [38]
                    530:        X68kKey_I,                              // [39]
                    531:        X68kKey_O,                              // [3a]
                    532:        X68kKey_P,                              // [3b]
                    533:        X68kKey_at,                             // [3c]
                    534:        X68kKey_bracketleft,    // [3d]
                    535:        X68kKey_hira,                   // [3e]
                    536:        X68kKey_zenkaku,                // [3f]
                    537: 
1.1.1.19! root      538:        NoKey,                                  // [40]
1.1.1.9   root      539:        X68kKey_UNDO,                   // [41]
1.1       root      540:        X68kKey_A,                              // [42]
                    541:        X68kKey_S,                              // [43]
                    542:        X68kKey_D,                              // [44]
                    543:        X68kKey_F,                              // [45]
                    544:        X68kKey_G,                              // [46]
                    545:        X68kKey_H,                              // [47]
                    546:        X68kKey_J,                              // [48]
                    547:        X68kKey_K,                              // [49]
                    548:        X68kKey_L,                              // [4a]
                    549:        X68kKey_semicolon,              // [4b]
                    550:        X68kKey_colon,                  // [4c]
                    551:        X68kKey_bracketright,   // [4d]
1.1.1.19! root      552:        X68kKey_OPT1,                   // [4e]
        !           553:        X68kKey_OPT2,                   // [4f]
1.1       root      554: 
1.1.1.9   root      555:        X68kKey_XF1,                    // [50]
                    556:        X68kKey_XF2,                    // [51]
1.1       root      557:        X68kKey_Z,                              // [52]
                    558:        X68kKey_X,                              // [53]
                    559:        X68kKey_C,                              // [54]
                    560:        X68kKey_V,                              // [55]
                    561:        X68kKey_B,                              // [56]
1.1.1.5   root      562:        X68kKey_N,                              // [57]
                    563:        X68kKey_M,                              // [58]
1.1       root      564:        X68kKey_comma,                  // [59]
                    565:        X68kKey_period,                 // [5a]
                    566:        X68kKey_slash,                  // [5b]
                    567:        X68kKey_underscore,             // [5c]
1.1.1.9   root      568:        X68kKey_XF3,                    // [5d]
                    569:        X68kKey_XF4,                    // [5e]
                    570:        X68kKey_XF5,                    // [5f]
1.1       root      571: 
1.1.1.19! root      572:        X68kKey_HOME,                   // [60]
1.1       root      573:        X68kKey_PAD_plus,               // [61]
                    574:        X68kKey_PAD_minus,              // [62]
                    575:        X68kKey_PAD_7,                  // [63]
                    576:        X68kKey_PAD_8,                  // [64]
                    577:        X68kKey_PAD_9,                  // [65]
                    578:        X68kKey_PAD_4,                  // [66]
                    579:        X68kKey_PAD_5,                  // [67]
                    580:        X68kKey_PAD_6,                  // [68]
                    581:        X68kKey_PAD_1,                  // [69]
                    582:        X68kKey_PAD_2,                  // [6a]
                    583:        X68kKey_PAD_3,                  // [6b]
                    584:        X68kKey_PAD_0,                  // [6c]
                    585:        X68kKey_PAD_decimal,    // [6d]
                    586:        X68kKey_PAD_enter,              // [6e]
                    587:        X68kKey_PAD_CLR,                // [6f]
                    588: 
1.1.1.19! root      589:        X68kKey_ROLLUP,                 // [70]
        !           590:        X68kKey_ROLLDOWN,               // [71]
1.1       root      591:        X68kKey_F1,                             // [72]
                    592:        X68kKey_F2,                             // [73]
                    593:        X68kKey_F3,                             // [74]
                    594:        X68kKey_F4,                             // [75]
                    595:        X68kKey_F5,                             // [76]
                    596:        X68kKey_F6,                             // [77]
                    597:        X68kKey_F7,                             // [78]
                    598:        X68kKey_F8,                             // [79]
                    599:        X68kKey_F9,                             // [7a]
                    600:        X68kKey_F10,                    // [7b]
                    601:        X68kKey_PAD_multiply,   // [7c]
                    602:        X68kKey_PAD_divide,             // [7d]
                    603:        X68kKey_PAD_equal,              // [7e]
                    604:        X68kKey_PAD_comma,              // [7f]
                    605: };

unix.superglobalmegacorp.com

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