Annotation of nono/vm/romemu_luna.cpp, revision 1.1.1.14

1.1       root        1: //
                      2: // nono
1.1.1.2   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.13  root        7: //
1.1.1.7   root        8: // LUNA シリーズの ROM エミュレーション共通部分
1.1.1.10  root        9: //
1.1.1.13  root       10: 
1.1.1.10  root       11: // IODevice
                     12: //    |
                     13: //    +-- ROMDevice (LoadROM()、ウェイト、マスク等を持つ)
                     14: //    |     |
                     15: //    |     +-- PROMDevice    (LUNA* の PROM)
                     16: //    |     +-- IPLROM1Device (X680x0 の IPLROM 後半)
                     17: //    |     +-- IPLROM2Device (X680x0 の IPLROM 前半)
                     18: //    |     +-- CGROMDevice   (X680x0 の CGROM)
                     19: //    |     |
                     20: //    |     |  +-------------------+
                     21: //    |     +--| LunaPROMEmuDevice | (LUNA PROM エミュレーションの共通部分)
                     22: //    |        +-------------------+
                     23: //    |           |
1.1.1.14! root       24: //    |           +-- Luna1PROMEmuDevice   (LUNA-I の PROM エミュレーション)
        !            25: //    |           +-- Luna88kPROMEmuDevice (LUNA-88K の PROM エミュレーション)
1.1.1.10  root       26: //    |
                     27: //    +-- PROM0Device   (LUNA* のブートページ切り替え用プロキシ)
                     28: //    +-- IPLROM0Device (X680x0 のブートページ切り替え用プロキシ)
1.1.1.2   root       29: 
                     30: #include "romemu_luna.h"
1.1.1.14! root       31: #include "bt45x.h"
1.1.1.9   root       32: #include "lunafb.h"
1.1       root       33: #include "mainapp.h"
1.1.1.14! root       34: #include "mainram.h"
1.1       root       35: #include "mk48t02.h"
1.1.1.13  root       36: #include "mpu.h"
1.1.1.14! root       37: #include "pio.h"
1.1.1.13  root       38: #include "prom.h"
1.1       root       39: #include "sio.h"
                     40: #include "spc.h"
1.1.1.7   root       41: #include "ufs.h"
1.1       root       42: 
                     43: // コンストラクタ
                     44: LunaPROMEmuDevice::LunaPROMEmuDevice()
1.1.1.14! root       45:        : inherited(OBJ_PROM)
1.1       root       46: {
1.1.1.10  root       47:        // LUNA では ROM への書き込みは何も起きない
                     48:        write_op = 0;
1.1       root       49: }
                     50: 
                     51: // デストラクタ
                     52: LunaPROMEmuDevice::~LunaPROMEmuDevice()
                     53: {
                     54: }
                     55: 
1.1.1.14! root       56: // 初期化
1.1       root       57: bool
                     58: LunaPROMEmuDevice::Init()
                     59: {
1.1.1.14! root       60:        if (inherited::Init() == false) {
        !            61:                return false;
        !            62:        }
        !            63: 
        !            64:        bt45x = GetBT45xDevice();
        !            65:        lunafb = GetLunafbDevice();
        !            66:        mainram = GetMainRAMDevice();
        !            67:        nvram = GetMK48T02Device();
        !            68:        sio = GetSIODevice();
        !            69:        spc = GetSPCDevice();
1.1       root       70: 
                     71:        return true;
                     72: }
                     73: 
1.1.1.2   root       74: uint64
1.1       root       75: LunaPROMEmuDevice::Read32(uint32 addr)
                     76: {
1.1.1.10  root       77:        // ROM からのロングワードアクセスでだけ謎の I/O 空間が見える。
                     78:        // addr をマスクする前に評価すること。
1.1.1.14! root       79:        if ((mpu->GetPaddr() & 0xff000000) == baseaddr) {
1.1.1.9   root       80:                switch (addr) {
                     81:                 case ROMIO_INIT:
1.1.1.2   root       82:                        return ROM_Init();
1.1       root       83: 
1.1.1.9   root       84:                 case ROMIO_KEYIN:
1.1.1.7   root       85:                        ROM_Keyin();
                     86:                        return 0;
1.1       root       87: 
1.1.1.9   root       88:                 case ROMIO_CLOSE:
1.1.1.7   root       89:                        ROM_Close();
                     90:                        return 0;
1.1       root       91: 
1.1.1.9   root       92:                 case ROMIO_ENTRY:
1.1.1.7   root       93:                        return ROM_Entry();
1.1.1.6   root       94: 
1.1       root       95:                 default:
                     96:                        break;
                     97:                }
                     98:        }
1.1.1.2   root       99: 
1.1.1.10  root      100:        return inherited::Read32(addr);
1.1       root      101: }
                    102: 
1.1.1.7   root      103: // デバイスの初期化の共通部分。(継承クラスの ROM_Init() から呼ぶ)
                    104: void
                    105: LunaPROMEmuDevice::InitDevice()
1.1       root      106: {
1.1.1.14! root      107:        auto pio1 = GetPIO1Device();
        !           108: 
1.1       root      109:        // 初期パレット
1.1.1.4   root      110:        // 偶数番は白(R/G/B=15/15/15)、奇数番は黒(0/0/0)。
1.1.1.14! root      111:        uint8 val = 0xff;
        !           112:        bt45x->Write(0, 0);     // select palette
1.1.1.4   root      113:        for (int i = 0; i < 16; i++) {
1.1.1.14! root      114:                bt45x->Write(1, val);   // R
        !           115:                bt45x->Write(1, val);   // G
        !           116:                bt45x->Write(1, val);   // B
        !           117:                val ^= 0xff;
1.1.1.4   root      118:        }
1.1       root      119: 
                    120:        // SCSI
                    121:        // BDID の書き込みによってホストデバイスがバスにアタッチされる構造なので。
1.1.1.14! root      122:        spc->Write(SPC::BDID, 7);
1.1       root      123: 
1.1.1.7   root      124:        // キーボード(chB)を初期化
1.1.1.14! root      125:        sio->Write(3, 0x01);            // CR1
        !           126:        sio->Write(3, 0x10);            //    RX Int(all char)
        !           127:        sio->Write(3, 0x04);            // CR4
        !           128:        sio->Write(3, 0x44);            //    Stop 1bit
        !           129:        sio->Write(3, 0x03);            // CR3
        !           130:        sio->Write(3, 0xc1);            //    RX Enable, 8bit
        !           131:        sio->Write(3, 0x05);            // CR5
        !           132:        sio->Write(3, 0x68);            //    TX Enable, 8bit
1.1.1.12  root      133: 
                    134:        // LED を(明示的に)オフ、マウスサンプリングをオフ
1.1.1.14! root      135:        sio->Write(2, 0x00);
        !           136:        sio->Write(2, 0x01);
        !           137:        sio->Write(2, 0x20);
        !           138: 
        !           139:        // 電源オフをキャンセル。
        !           140:        // 実 PROM では、リセット後に PIO のモードセットを行っている。
        !           141:        // モードセットを行うと PortC のビットが %0 になる = 電源オフなので、
        !           142:        // 即座にこれをキャンセルしている。
        !           143:        // ROMEmu ではモードセットを行っていないが、キャンセルだけ発行しておく。
        !           144:        pio1->Write(3, 0x09);
1.1.1.7   root      145: }
1.1.1.2   root      146: 
1.1.1.7   root      147: // スクリーンを初期化
                    148: void
1.1.1.13  root      149: LunaPROMEmuDevice::InitScreen()
1.1.1.7   root      150: {
1.1.1.14! root      151:        lunafb->EmuInitScreen();
1.1.1.13  root      152: 
                    153:        screen_w = 80;
                    154:        screen_h = 32;
                    155:        cursor_x = 0;
                    156:        cursor_y = 0;
                    157: 
                    158:        // 表示範囲はざっくりセンタリングする
                    159:        origin_px = (1280 - screen_w * 12) / 2;
                    160:        origin_py = (1024 - screen_h * 24) / 2;
                    161:        // 横は 48ドット境界から始めておく。
                    162:        // こうすると1(,2)文字目の24ビットが必ずワード境界から始まるため。
                    163:        // 今となっては任意の場所から文字が描画できるようになったので揃える
                    164:        // 必要はなくなったが、依然このほうがアクセス効率はいいので。
                    165:        origin_px = (origin_px / 48) * 48;
                    166: 
1.1.1.2   root      167:        inputbuf.clear();
                    168:        inputpos = 0;
                    169:        is_shift = false;
1.1.1.3   root      170:        mousecnt = 0;
1.1.1.13  root      171: }
1.1       root      172: 
1.1.1.13  root      173: // タイトルを出力
                    174: void
                    175: LunaPROMEmuDevice::PrintTitle(const char *machine_name)
                    176: {
                    177:        Print("NONO %d.%d.%d Emulated ROM Monitor for %s\n\n",
1.1.1.7   root      178:                NONO_MAJOR_VER, NONO_MINOR_VER, NONO_PATCH_VER, machine_name);
1.1.1.13  root      179: }
                    180: 
                    181: // 1文字出力
                    182: void
                    183: LunaPROMEmuDevice::Putc(uint ch)
                    184: {
                    185:        uint px = origin_px + cursor_x * 12;
                    186:        uint py = origin_py + cursor_y * 24;
                    187: 
                    188:        // カーソル位置の反転を元に戻す
1.1.1.14! root      189:        lunafb->EmuPutc(px, py, ' ', ROP::INV2);
1.1.1.13  root      190: 
                    191:        if (ch == LF) {
                    192:  put_LF:
                    193:                cursor_x = 0;
                    194:                if (cursor_y < screen_h - 1) {
                    195:                        cursor_y++;
                    196:                } else {
                    197:                        // 上スクロールして..
1.1.1.14! root      198:                        lunafb->EmuScrollY(origin_py, origin_py + 24, (screen_h - 1) * 24);
1.1.1.13  root      199:                        // 最終行を消す
1.1.1.14! root      200:                        lunafb->EmuFill(0, py, 1280, 24, 0);
1.1.1.13  root      201:                }
                    202:        } else if (ch == LEFT) {
                    203:                if (cursor_x > 0) {
                    204:                        cursor_x--;
                    205:                } else {
                    206:                        cursor_y--;
                    207:                        cursor_x = screen_w - 1;
                    208:                }
                    209:        } else if (ch == RIGHT) {
                    210:                if (cursor_x < screen_w - 1) {
                    211:                        cursor_x++;
                    212:                } else {
                    213:                        cursor_y++;
                    214:                        cursor_x = 0;
                    215:                }
                    216:        } else {
                    217:                if (cursor_x < screen_w - 1) {
1.1.1.14! root      218:                        lunafb->EmuPutc(px, py, ch);
1.1.1.13  root      219:                        cursor_x++;
                    220:                } else {
1.1.1.14! root      221:                        lunafb->EmuPutc(px, py, ch);
1.1.1.13  root      222:                        goto put_LF;
                    223:                }
                    224:        }
                    225: 
                    226:        // カーソル位置を再計算して描画 (文字を反転)
                    227:        px = origin_px + cursor_x * 12;
                    228:        py = origin_py + cursor_y * 24;
1.1.1.14! root      229:        lunafb->EmuPutc(px, py, ' ', ROP::INV2);
1.1.1.13  root      230: }
                    231: 
                    232: // 文字列 s を出力
                    233: void
                    234: LunaPROMEmuDevice::Print(const std::string& s)
                    235: {
                    236:        for (auto *p = s.c_str(); *p; p++) {
                    237:                Putc(*p);
                    238:        }
                    239: }
                    240: 
                    241: // 文字列 fmt... を出力
                    242: void
                    243: LunaPROMEmuDevice::Print(const char *fmt, ...)
                    244: {
                    245:        char buf[1024];
                    246:        va_list ap;
                    247: 
                    248:        va_start(ap, fmt);
                    249:        vsnprintf(buf, sizeof(buf), fmt, ap);
                    250:        va_end(ap);
                    251: 
                    252:        for (char *p = buf; *p; p++) {
                    253:                Putc(*p);
                    254:        }
1.1       root      255: }
                    256: 
1.1.1.7   root      257: // ROM 処理のクローズ
                    258: void
1.1.1.2   root      259: LunaPROMEmuDevice::ROM_Close()
1.1       root      260: {
1.1.1.11  root      261:        // SIO をリセットしておく。
                    262:        // SIO のバッファにデータが残っていると、NetBSD のブートローダが
                    263:        // 起動してこないようだ。リセットして RXEN を落としておけば大丈夫ぽい。
1.1.1.14! root      264:        sio->ResetHard(false);
1.1       root      265: }
                    266: 
1.1.1.2   root      267: // ROM プロンプトのキー入力。
1.1.1.7   root      268: // ゲストコードの割り込みハンドラから呼ばれて、キー入力で行を構成し、
                    269: // あるいは行が完成すればコマンドを実行する。
                    270: // 実行結果により画面を更新したりメンバ変数を更新する。
                    271: void
1.1.1.2   root      272: LunaPROMEmuDevice::ROM_Keyin()
1.1       root      273: {
1.1.1.14! root      274:        int asciicode = Getc();
        !           275: 
        !           276:        if (asciicode != -1) {
        !           277:                ProcessChar(asciicode);
        !           278:        }
        !           279: }
        !           280: 
        !           281: // キー入力。
        !           282: // 押されているキーの ASCII コードを返す。
        !           283: // キー入力が無いときは -1 を返す。
        !           284: int
        !           285: LunaPROMEmuDevice::Getc()
        !           286: {
        !           287:        // コントロールレジスタポインタを確実に 0 にするため読み捨てる
        !           288:        sio->Read(3);
        !           289: 
        !           290:        uint8 sr0 = sio->Read(3);
        !           291:        if ((sr0 & MPSCC::SR0_RXAVAIL) == 0) {
        !           292:                return -1;
        !           293:        }
        !           294: 
        !           295:        uint32 lunakey = sio->Read(2);
1.1       root      296: 
1.1.1.3   root      297:        // マウス入力の 2, 3バイト目は無視
                    298:        if (mousecnt > 0) {
                    299:                mousecnt--;
1.1.1.14! root      300:                return -1;
1.1.1.3   root      301:        }
                    302: 
1.1.1.2   root      303:        // SHIFT キーだけ状態を持つので先に処理
                    304:        if (lunakey == 0x0c || lunakey == 0x0d) {       // 左右SHIFT押下
                    305:                is_shift = true;
1.1.1.14! root      306:                return -1;
1.1.1.2   root      307:        }
                    308:        if (lunakey == 0x8c || lunakey == 0x8d) {       // 左右SHIFT開放
1.1       root      309:                is_shift = false;
1.1.1.14! root      310:                return -1;
1.1.1.2   root      311:        }
1.1.1.3   root      312:        // マウスデータの1バイト目なら、後続2バイトをスキップ
                    313:        if ((lunakey & 0xf8) == 0x80) {
                    314:                mousecnt = 2;
1.1.1.14! root      315:                return -1;
1.1.1.3   root      316:        }
                    317:        // キー開放は無視してよい
1.1.1.2   root      318:        if ((lunakey & 0x80)) {
1.1.1.14! root      319:                return -1;
1.1.1.2   root      320:        }
1.1       root      321: 
1.1.1.9   root      322:        // キーコードから文字を取得
1.1.1.14! root      323:        int asciicode;
1.1.1.9   root      324:        if (is_shift) {
                    325:                asciicode = lunakey2shifttable[lunakey];
                    326:        } else {
                    327:                asciicode = lunakey2asciitable[lunakey];
                    328:        }
1.1.1.14! root      329:        if (asciicode == 0) {
        !           330:                return -1;
1.1.1.9   root      331:        }
1.1.1.14! root      332: 
        !           333:        return asciicode;
1.1.1.9   root      334: }
                    335: 
                    336: // キー入力ハンドラ (キー入力割り込みによって呼ばれる)。
                    337: // 引数 asciicode は概ね ASCII コード (ただし 0x1c..0x1f が上下左右)。
                    338: void
1.1.1.14! root      339: LunaPROMEmuDevice::ProcessChar(char asciicode)
1.1.1.9   root      340: {
1.1.1.14! root      341:        // LUNA-I の場合、
1.1.1.9   root      342:        // 実機 PROM にはカーソル左右移動の機能はなく、カーソルは常に行末にいる。
                    343:        // そのためかどうか Delete も BackSpace と同じく1文字前を消す動作をして
                    344:        // いる。カーソル位置に文字はないので、Delete をそうするのはまあ分からん
                    345:        // でもない。
                    346:        // 一方、エミュレーション ROM では、カーソルの左右移動をサポートしてみた
                    347:        // ため Delete を「カーソル位置の文字を消す」にすることは出来るが、それは
                    348:        // それで実機と乖離が広がるので、どうしたもんか。
                    349: 
                    350:        switch (asciicode) {
                    351:         case BS:
                    352:                if (inputbuf.empty() == false && inputpos != 0) {
                    353:                        inputbuf.erase(--inputpos, 1);
1.1.1.13  root      354:                        Putc(LEFT);
                    355:                        for (int i = inputpos; i < inputbuf.size(); i++) {
                    356:                                Putc(inputbuf[i]);
                    357:                        }
                    358:                        Putc(' ');
                    359:                        for (int i = 0; i < 1 + inputbuf.size() - inputpos; i++) {
                    360:                                Putc(LEFT);
                    361:                        }
1.1       root      362:                }
1.1.1.2   root      363:                break;
1.1.1.9   root      364: 
                    365:         case LF:
1.1.1.2   root      366:                // 改行
1.1.1.13  root      367:                Putc(asciicode);
                    368:                prompt_y = cursor_y;
1.1.1.9   root      369:                // コマンド実行
1.1.1.7   root      370:                Command();
1.1.1.9   root      371:                // プロンプトを更新
                    372:                ClearPrompt();
1.1.1.2   root      373:                break;
1.1.1.9   root      374: 
                    375:         case LEFT:
1.1.1.2   root      376:                if (inputpos > 0) {
                    377:                        inputpos--;
1.1.1.13  root      378:                        Putc(LEFT);
1.1       root      379:                }
1.1.1.2   root      380:                break;
1.1.1.9   root      381:         case RIGHT:
1.1.1.2   root      382:                if (inputpos < inputbuf.length()) {
1.1       root      383:                        inputpos++;
1.1.1.13  root      384:                        Putc(RIGHT);
1.1       root      385:                }
                    386:                break;
1.1.1.9   root      387: 
                    388:         case UP:
                    389:         case DOWN:
                    390:         case 0:        // キー割り当てなし、これは来ないはずだが一応
                    391:                return;
                    392: 
                    393:         default:       // 通常文字のはず
1.1.1.2   root      394:                inputbuf.insert(inputbuf.begin() + inputpos, asciicode);
1.1.1.13  root      395:                for (int i = inputpos; i < inputbuf.size(); i++) {
                    396:                        Putc(inputbuf[i]);
                    397:                }
                    398:                for (int i = 0; i < inputbuf.size() - inputpos - 1; i++) {
                    399:                        Putc(LEFT);
                    400:                }
1.1.1.2   root      401:                inputpos++;
                    402:                break;
1.1       root      403:        }
1.1.1.2   root      404: }
1.1       root      405: 
1.1.1.9   root      406: // 入力バッファを初期化する。
                    407: void
                    408: LunaPROMEmuDevice::ClearPrompt()
                    409: {
1.1.1.13  root      410:        prompt_y = cursor_y;
1.1.1.9   root      411:        // 入力行をクリア
                    412:        inputbuf.clear();
                    413:        inputpos = 0;
                    414: 
1.1.1.13  root      415:        Print(prompt);
1.1.1.9   root      416: }
                    417: 
                    418: // NVRAM のチェックサムを返す
                    419: uint8
                    420: LunaPROMEmuDevice::CalcNVRAMCsum() const
                    421: {
                    422:        uint8 eor = 0;
                    423:        for (uint32 addr = 0x20; addr < 0x560; addr++) {
                    424:                eor ^= nvram->Peek(addr);
                    425:        }
                    426:        return eor;
                    427: }
                    428: 
                    429: // NVRAM のチェックサムを計算して書き込む
                    430: void
                    431: LunaPROMEmuDevice::WriteNVRAMCsum()
                    432: {
                    433:        uint8 eor = CalcNVRAMCsum();
                    434: 
                    435:        nvram->Write(0x001c, eor);
                    436:        nvram->Write(0x001d, eor);
                    437:        nvram->Write(0x001e, eor);
                    438: }
                    439: 
                    440: // NVRAM のマジックとチェックサムを照合する
                    441: bool
                    442: LunaPROMEmuDevice::VerifyNVRAM() const
                    443: {
                    444:        if (nvram->PeekString(0x0004) != "<nv>") {
                    445:                return false;
                    446:        }
                    447: 
                    448:        uint8 eor = CalcNVRAMCsum();
                    449:        for (uint32 addr = 0x1c; addr < 0x1f; addr++) {
                    450:                if (nvram->Peek(addr) != eor) {
                    451:                        return false;
                    452:                }
                    453:        }
                    454:        return true;
1.1       root      455: }
                    456: 
1.1.1.10  root      457: // -X オプションで指定されたホストファイルをロードする。
1.1       root      458: // ロードできればエントリポイントを返す。
1.1.1.10  root      459: // exec_file が指定されている時に呼ぶこと。
1.1       root      460: uint32
                    461: LunaPROMEmuDevice::LoadHostFile()
                    462: {
1.1.1.10  root      463:        assert(gMainApp.exec_file);
1.1       root      464: 
1.1.1.14! root      465:        LoadInfo info(gMainApp.exec_file);
        !           466:        if (mainram->LoadFromFile(&info)) {
        !           467:                Print("Host program loaded.  Entry point = $%08x\n", info.entry);
        !           468:                return info.entry;
1.1       root      469:        } else {
1.1.1.13  root      470:                Print("** Couldn't load specified host program.\n");
1.1.1.14! root      471:                return 0;
1.1       root      472:        }
                    473: }
                    474: 
1.1.1.7   root      475: // bootinfo に従ってゲストから起動先をロードする。
1.1       root      476: // 成功すればエントリポイントを返す。
1.1.1.14! root      477: // 失敗ならをエラーメッセージを errmsg にセットして (uint32)-1 を返す。
1.1       root      478: uint32
1.1.1.7   root      479: LunaPROMEmuDevice::LoadGuestFile(const bootinfo_t& bootinfo)
1.1       root      480: {
1.1.1.7   root      481:        const int& dkpart = bootinfo.dkpart;
                    482:        const int& dkunit = bootinfo.dkunit;
                    483:        const std::string& dkfile = bootinfo.dkfile;
1.1       root      484: 
                    485:        // ユニット (今は SCSI ID=6 決め打ち)
                    486:        int id = 6;
1.1.1.14! root      487:        SCSITarget *target = spc->GetTarget(id);
1.1       root      488:        if (target == NULL) {
                    489:                errmsg = "No bootable disks";
                    490:                putmsg(0, "%s", errmsg.c_str());
1.1.1.14! root      491:                return -1;
1.1       root      492:        }
1.1.1.3   root      493:        if (target->GetDevType() != SCSI::DevType::HD) {
1.1       root      494:                errmsg = "No bootable disks";
                    495:                putmsg(0, "%s", errmsg.c_str());
1.1.1.14! root      496:                return -1;
1.1       root      497:        }
                    498: 
1.1.1.10  root      499:        SCSIDisk *hd = dynamic_cast<SCSIDisk*>(target);
1.1       root      500:        putmsg(2, "%s SCSIHD[%d] found", __func__, id);
                    501: 
                    502:        // +0 セクタ目(512byte)に Sun disklabel
                    503:        scd_dk_label dk;
1.1.1.10  root      504:        if (hd->Peek(&dk, 0, sizeof(dk)) == false) {
1.1       root      505:                putmsg(0, "SCSIHD[%d] ReadSector failed", id);
                    506:                errmsg = string_format("dk%d Read disklabel failed.", dkunit);
1.1.1.14! root      507:                return -1;
1.1       root      508:        }
                    509: 
                    510:        // +$1fc の MAGIC をチェック
                    511:        uint32 magic = be16toh(dk.magic);
                    512:        if (magic != scd_dk_label::DKL_MAGIC) {
                    513:                putmsg(0, "SCSIHD[%d] Bad magic 0x%04x (!= 0x%x)",
                    514:                        id, magic, scd_dk_label::DKL_MAGIC);
                    515:                errmsg = string_format("dk%d Bad disklabel magic.", dkunit);
1.1.1.14! root      516:                return -1;
1.1       root      517:        }
                    518: 
                    519:        // チェックサム照合は手抜きで省略
                    520: 
                    521:        // 指定パーティションの開始位置とサイズ
                    522:        if (loglevel >= 2) {
                    523:                // デバッグ用に全部表示
                    524:                for (int i = 0; i < 8; i++) {
1.1.1.7   root      525:                        putmsgn("%s partition %c: { start=%8u size=%8u }", __func__,
1.1       root      526:                                'a' + i,
                    527:                                be32toh(dk.map[i].blkno),
                    528:                                be32toh(dk.map[i].nblk));
                    529:                }
                    530:        }
                    531:        uint32 part_start = be32toh(dk.map[dkpart].blkno);
                    532:        uint32 part_size  = be32toh(dk.map[dkpart].nblk);
                    533:        putmsg(1, "%s partition=%c, start=%u size=%u", __func__,
                    534:                dkpart + 'a', part_start, part_size);
                    535: 
                    536:        // ファイルシステムをオープン (マウントっぽいイメージ)
                    537:        Filesys fsys(this);
1.1.1.7   root      538:        if (fsys.Mount(hd, part_start, part_size) == false) {
                    539:                errmsg = string_format("dk%d,%c Open ffs failed: %s",
                    540:                        dkunit, dkpart + 'a', fsys.errstr.c_str());
                    541:                putmsg(0, "%s: %s", __func__, errmsg.c_str());
1.1.1.14! root      542:                return -1;
1.1       root      543:        }
                    544: 
1.1.1.7   root      545:        // ファイルを探してオープンする
                    546:        inodefile f(this);
                    547:        if (fsys.OpenFile(f, dkfile) == false) {
                    548:                errmsg = string_format("dk%d,%c,%s open failed: %s",
                    549:                        dkunit, dkpart + 'a', dkfile.c_str(), fsys.errstr.c_str());
                    550:                putmsg(0, "%s: %s", __func__, errmsg.c_str());
1.1.1.14! root      551:                return -1;
1.1       root      552:        }
1.1.1.7   root      553: 
1.1       root      554:        // ファイル本体を読み込み
1.1.1.7   root      555:        fsys.ReadData(f);
1.1       root      556: 
                    557:        // ロード
                    558:        std::string name = string_format("SCSIHD %d,%c:%s",
1.1.1.7   root      559:                id, dkpart + 'a', dkfile.c_str());
1.1.1.14! root      560:        LoadInfo info(name.c_str(), f.data.data(), f.data.size());
        !           561:        if (mainram->LoadFromData(&info) == false) {
        !           562:                errmsg = string_format("dk%d,%c,%s load failed",
        !           563:                        dkunit, dkpart + 'a', dkfile.c_str());
        !           564:                putmsg(0, "%s: %s", __func__, errmsg.c_str());
        !           565:                return -1;
        !           566:        }
        !           567: 
        !           568:        if (info.entry == -1) {
1.1.1.7   root      569:                errmsg = string_format("dk%d,%c,%s not executable",
                    570:                        dkunit, dkpart + 'a', dkfile.c_str());
1.1.1.14! root      571:                putmsg(0, "%s: %s", __func__, errmsg.c_str());
        !           572:                return -1;
1.1       root      573:        }
                    574: 
1.1.1.14! root      575:        return info.entry;
1.1       root      576: }
                    577: 
1.1.1.7   root      578: // キーコードから文字への変換
                    579: /*static*/ const uint8
                    580: LunaPROMEmuDevice::lunakey2asciitable[] = {
1.1.1.9   root      581:         0,   0,   0,   0,   0,   0,   0,   0,
                    582:         0,   0,   0,   0,   0,   0,   0,   0,
                    583:         0,  BS,  LF,   0, ' ',   0,   0,   0,
                    584:         0,   0,   0,   0,  UP,LEFT,RIGHT,DOWN,
1.1.1.7   root      585:         0,   0,  '1', '2', '3', '4', '5', '6',
                    586:        '7', '8', '9', '0', '-', '^', '\\', 0,
                    587:         0,   0,  'q', 'w', 'e', 'r', 't', 'y',
                    588:        'u', 'i', 'o', 'p', '@', '[',  0,   0,
                    589:         0,   0,  'a', 's', 'd', 'f', 'g', 'h',
                    590:        'j', 'k', 'l', ';', ':', ']',  0,   0,
                    591:         0,   0,  'z', 'x', 'c', 'v', 'b', 'n',
                    592:        'm', ',', '.', '/',  0,   0,   0,   0,
1.1.1.13  root      593:         0,  '+', '-', '7', '8', '9', '4', '5',
                    594:        '6', '1', '2', '3', '0', '.', LF,   0,
                    595:         0,   0,   0,   0,   0,   0,   0,   0,
                    596:         0,   0,   0,   0,  '*', '/', '=', ',',
1.1.1.7   root      597: };
                    598: /*static*/ const uint8
                    599: LunaPROMEmuDevice::lunakey2shifttable[] = {
1.1.1.9   root      600:         0,   0,   0,   0,   0,   0,   0,   0,
                    601:         0,   0,   0,   0,   0,   0,   0,   0,
                    602:         0,  BS,  LF,   0, ' ',   0,   0,   0,
                    603:         0,   0,   0,   0,  UP,LEFT,RIGHT,DOWN,
                    604:         0,   0,  '!', '\"','#', '$', '%', '&',
                    605:        '\'','(', ')', ' ', '=', '~', '|',  0,          // XXX SHIFT+'0'は?
1.1.1.7   root      606:         0,   0,  'Q', 'W', 'E', 'R', 'T', 'Y',
                    607:        'U', 'I', 'O', 'P', '`', '{',  0,   0,
                    608:         0,   0,  'A', 'S', 'D', 'F', 'G', 'H',
                    609:        'J', 'K', 'L', '+', '*', '}',  0,   0,
                    610:         0,   0,  'Z', 'X', 'C', 'V', 'B', 'N',
                    611:        'M', '<', '>', '?', '_',  0,   0,   0,
1.1.1.13  root      612:         0,  '+', '-', '7', '8', '9', '4', '5',
                    613:        '6', '1', '2', '3', '0', '.', LF,   0,
                    614:         0,   0,   0,   0,   0,   0,   0,   0,
                    615:         0,   0,   0,   0,  '*', '/', '=', ',',
1.1.1.7   root      616: };

unix.superglobalmegacorp.com

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