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

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

unix.superglobalmegacorp.com

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