Annotation of nono/vm/romemu_luna88k.cpp, revision 1.1.1.2

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.2 ! root        7: // LUNA88K の ROM エミュレーション
        !             8: 
        !             9: //             IODevice
        !            10: //                |
        !            11: //     +----------+----------+
        !            12: //     v                     v
        !            13: // ROMDevice         Luna88KPROMEmuDeivce (ROM エミュレーション)
        !            14: //     |
        !            15: //     v
        !            16: // PROMDevice (実ROM)
        !            17: 
        !            18: #include "romemu_luna88k.h"
1.1       root       19: #include "aout.h"
                     20: #include "bt454.h"
                     21: #include "mainapp.h"
                     22: #include "memorystream.h"
                     23: #include "ram.h"
                     24: #include "spc.h"
                     25: 
                     26: // コンストラクタ
                     27: Luna88kPROMEmuDevice::Luna88kPROMEmuDevice()
                     28: {
                     29:        devaddr = baseaddr;
1.1.1.2 ! root       30:        devlen = 256 * 1024;
        !            31: 
        !            32:        romdatalen = 1024;      // サイズは適当
        !            33:        romdata.reset(new uint8 [romdatalen]);
1.1       root       34: }
                     35: 
                     36: // デストラクタ
                     37: Luna88kPROMEmuDevice::~Luna88kPROMEmuDevice()
                     38: {
                     39: }
                     40: 
                     41: bool
                     42: Luna88kPROMEmuDevice::Init()
                     43: {
1.1.1.2 ! root       44:        MemoryStreamBE ms(romdata.get());
1.1       root       45: 
                     46:        // リセットベクタは本来2ワードだけだが他のベクタは使わないので
                     47:        // 直接コードを書く。
                     48:        uint32 hi = ROMIO_IPL >> 16;
                     49:        uint32 lo = ROMIO_IPL & 0xffff;
                     50:        ms.Write32(0x5c400000 | hi);    // or.u r2, r0, (ROMIO_IPL >> 16)
                     51:        ms.Write32(0x58420000 | lo);    // or   r2, r2, (ROMIO_IPL & 0xffff)
                     52:        ms.Write32(0xf4221400);                 // ld   r1, r2, r0
                     53:        ms.Write32(0xf400c001);                 // jmp  r1
                     54: 
                     55:        return true;
                     56: }
                     57: 
                     58: void
                     59: Luna88kPROMEmuDevice::ResetHard()
                     60: {
                     61:        ipl_done = false;
                     62: }
                     63: 
                     64: // アドレスデコーダ
                     65: inline uint64
                     66: Luna88kPROMEmuDevice::Decoder(uint32 addr) const
                     67: {
1.1.1.2 ! root       68:        // 折り返しなし
1.1       root       69:        return addr - baseaddr;
                     70: }
                     71: 
                     72: uint64
1.1.1.2 ! root       73: Luna88kPROMEmuDevice::Read8(uint32 addr)
        !            74: {
        !            75:        // LUNA88K で Read8 呼ばれるんだっけ?
        !            76: 
        !            77:        uint64 offset = Decoder(addr) & (devlen - 1);
        !            78: 
        !            79:        // 謎の IO 空間は(ロング)ワードアクセスのみ
        !            80:        if (offset < romdatalen) {
        !            81:                return romdata[offset];
        !            82:        } else {
        !            83:                return 0xff;
        !            84:        }
        !            85: }
        !            86: 
        !            87: uint64
        !            88: Luna88kPROMEmuDevice::Read16(uint32 addr)
        !            89: {
        !            90:        // LUNA88K で Read16 呼ばれるんだっけ?
        !            91: 
        !            92:        uint64 offset = Decoder(addr) & (devlen - 1);
        !            93: 
        !            94:        // 謎の IO 空間は(ロング)ワードアクセスのみ
        !            95:        if (offset < romdatalen) {
        !            96:                return be16toh(*(uint16 *)(&romdata[offset]));
        !            97:        } else {
        !            98:                return 0xffff;
        !            99:        }
        !           100: }
        !           101: 
        !           102: uint64
1.1       root      103: Luna88kPROMEmuDevice::Read32(uint32 addr)
                    104: {
                    105:        uint64 offset = Decoder(addr);
                    106: 
                    107:        // (ロング)ワードアクセスでだけ謎の I/O 空間が見える
                    108:        switch (offset) {
                    109:         case ROMIO_IPL - baseaddr:
                    110:                if (!ipl_done)
                    111:                        return IPL();
                    112:                break;
                    113:        }
                    114: 
1.1.1.2 ! root      115:        offset &= (devlen - 1);
        !           116:        if (offset < romdatalen) {
        !           117:                return be32toh(*(uint32 *)(&romdata[offset]));
        !           118:        } else {
        !           119:                return 0xffffffff;
        !           120:        }
        !           121: }
        !           122: 
        !           123: uint64
        !           124: Luna88kPROMEmuDevice::Write8(uint32 addr, uint32 data)
        !           125: {
        !           126:        return 0;
        !           127: }
        !           128: 
        !           129: uint64
        !           130: Luna88kPROMEmuDevice::Write16(uint32 addr, uint32 data)
        !           131: {
        !           132:        return 0;
        !           133: }
        !           134: 
        !           135: uint64
        !           136: Luna88kPROMEmuDevice::Write32(uint32 addr, uint32 data)
        !           137: {
        !           138:        return 0;
        !           139: }
        !           140: 
        !           141: uint64
        !           142: Luna88kPROMEmuDevice::Peek8(uint32 addr)
        !           143: {
        !           144:        uint64 offset = Decoder(addr) & (devlen - 1);
        !           145: 
        !           146:        if (offset < romdatalen) {
        !           147:                return romdata[offset];
        !           148:        } else {
        !           149:                return 0xff;
        !           150:        }
1.1       root      151: }
                    152: 
                    153: // 起動時の処理を行う。
                    154: // 成功すればエントリポイント、失敗すれば 0 を返す。
                    155: uint32
                    156: Luna88kPROMEmuDevice::IPL()
                    157: {
                    158:        uint32 entry = 0;
                    159: 
                    160:        ipl_done = true;
                    161: 
                    162:        // ベクタテーブルを rte で埋めておく
                    163:        for (int i = 0; i < 512; i++) {
                    164:                gRAM->Write32(i * 8, 0xf400fc00 /* rte */);
                    165:        }
                    166: 
                    167:        // ROM の機能テーブル
                    168:        // 0x00001100 からあるようだ
                    169:        // 0x0000110c GETC()
                    170:        // 0x00001110 PUTC(c)
                    171:        // 0x00001114 ビットマッププレーンの有効状態が入っている。
                    172:        //  bit0: plane0 有効
                    173:        //  bit1..7: plane1..7 有効
                    174:        gRAM->Write32(0x0000110c, 0x00001300);
                    175:        gRAM->Write32(0x00001110, 0x00001400);
                    176:        gRAM->Write32(0x00001114, 0x00000001);
                    177: 
                    178:        // ROM GETC エミュレータ
                    179:        gRAM->Write32(0x00001300, 0xfc000c00);  // internal inst getc
                    180:        gRAM->Write32(0x00001304, 0xf400c001);  // jmp r1
                    181: 
                    182:        // ROM PUTC エミュレータ
                    183:        gRAM->Write32(0x00001400, 0xfc001000);  // internal inst putc
                    184:        gRAM->Write32(0x00001404, 0xf400c001);  // jmp r1
                    185: 
                    186:        // 初期パレット
1.1.1.2 ! root      187:        // 偶数が 0xf, 奇数が 0
        !           188:        for (int i = 0; i < 16; i++) {
        !           189:                gBT454->Write8(0, i << 4);      // select palette
        !           190:                uint32 c = ((i & 1) ? 0 : 0xf) << 4;
        !           191:                gBT454->Write8(1, c);   // R
        !           192:                gBT454->Write8(1, c);   // G
        !           193:                gBT454->Write8(1, c);   // B
        !           194:        }
1.1       root      195: 
                    196:        // SCSI
                    197:        // BDID の書き込みによってホストデバイスがバスにアタッチされる構造なので。
                    198:        gSPC->Write8(SPC::BDID, 7);
                    199: 
                    200:        if (gMainApp.host_file) {
                    201:                // ホストのファイルを読み込んでエントリポイントアドレスを
                    202:                // この Read アクセスの読み出し値として返す。
                    203:                entry = gRAM->LoadFile(gMainApp.host_file, AOUT_MID_M88K);
                    204:        }
                    205: 
                    206:        return entry;
                    207: }

unix.superglobalmegacorp.com

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