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

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: 
1.1.1.3 ! root      186:        // XXX このへん romemu_luna と同じところは共通化したほうがいい
        !           187: 
1.1       root      188:        // 初期パレット
1.1.1.3 ! root      189:        // 偶数番は白(R/G/B=15/15/15)、奇数番は黒(0/0/0)。
        !           190:        uint8 val = 0xf0;
        !           191:        gBT454->Write8(0, 0);   // select palette
1.1.1.2   root      192:        for (int i = 0; i < 16; i++) {
1.1.1.3 ! root      193:                gBT454->Write8(1, val); // R
        !           194:                gBT454->Write8(1, val); // G
        !           195:                gBT454->Write8(1, val); // B
        !           196:                val ^= 0xf0;
1.1.1.2   root      197:        }
1.1       root      198: 
                    199:        // SCSI
                    200:        // BDID の書き込みによってホストデバイスがバスにアタッチされる構造なので。
                    201:        gSPC->Write8(SPC::BDID, 7);
                    202: 
                    203:        if (gMainApp.host_file) {
                    204:                // ホストのファイルを読み込んでエントリポイントアドレスを
                    205:                // この Read アクセスの読み出し値として返す。
                    206:                entry = gRAM->LoadFile(gMainApp.host_file, AOUT_MID_M88K);
1.1.1.3 ! root      207:                if (entry == 0) {
        !           208:                        // XXX まだコンソールがなくて停止できないのでとりあえず終了
        !           209:                        exit(1);
        !           210:                }
1.1       root      211:        }
                    212: 
                    213:        return entry;
                    214: }

unix.superglobalmegacorp.com

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