Annotation of nono/vm/cmmu.cpp, revision 1.1.1.10

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
1.1.1.4   root        7: //
1.1       root        8: // M88200 CMMU の I/O デバイス部分
1.1.1.4   root        9: //
1.1       root       10: 
                     11: // CMMU が確定しない場合はこのデバイスのログを使う。
1.1.1.2   root       12: // CMMU が確定したらそっちのデバイスログから出力する。
1.1       root       13: 
1.1.1.4   root       14: #include "cmmu.h"
1.1.1.6   root       15: #include "m88200.h"
1.1.1.9   root       16: #include "mainapp.h"
1.1       root       17: 
                     18: // コンストラクタ
                     19: CMMUDevice::CMMUDevice()
1.1.1.6   root       20:        : inherited(OBJ_CMMUIO)
1.1       root       21: {
                     22: }
                     23: 
                     24: // デストラクタ
                     25: CMMUDevice::~CMMUDevice()
                     26: {
                     27: }
                     28: 
1.1.1.6   root       29: // 初期化
1.1       root       30: bool
                     31: CMMUDevice::Init()
                     32: {
                     33:        // CMMU をポイントしておく
1.1.1.6   root       34:        for (int i = 0; i < cmmus.size(); i++) {
                     35:                cmmus[i] = gMainApp.FindObject<m88200>(OBJ_M88200(i));
                     36:        }
1.1       root       37: 
                     38:        return true;
                     39: }
                     40: 
                     41: // アドレスデコーダ
                     42: /*static*/ inline uint32
                     43: CMMUDevice::Decoder(uint32 addr)
                     44: {
                     45:        uint32 offset = addr & 0xfff;
                     46: 
                     47:        // BWP* の A5 はデコードされてない
                     48:        if (0x420 <= offset && offset < 0x440) {
                     49:                offset &= ~0x20;
                     50:        }
                     51:        // CDP*,CTP* の A4,A5 はデコードされていない
                     52:        if (0x800 <= offset && offset < 0x880) {
                     53:                offset &= ~0x30;
                     54:        }
                     55: 
                     56:        return offset;
                     57: }
                     58: 
1.1.1.7   root       59: busdata
1.1.1.8   root       60: CMMUDevice::Read(busaddr addr)
1.1       root       61: {
1.1.1.8   root       62:        busdata data;
1.1       root       63: 
1.1.1.8   root       64:        uint32 paddr = addr.Addr();
                     65:        uint32 id = (paddr >> 12) & 0xff;
1.1       root       66:        m88200 *cmmu = GetCMMU(id);
                     67:        if (cmmu == NULL) {
1.1.1.8   root       68:                putlog(3, "Read not-equipped CMMU[%u] $%08x", id, paddr);
1.1       root       69:                return 0xffffffff;
                     70:        }
                     71: 
1.1.1.8   root       72:        uint32 offset = Decoder(paddr);
1.1       root       73:        switch (offset) {
                     74:         case IDR:
                     75:                data = cmmu->GetIDR();
1.1.1.8   root       76:                cmmu->putlogf(2, lstr("IDR  -> $%08x", data.Data()));
1.1.1.7   root       77:                break;
1.1       root       78: 
                     79:         case SCR:
                     80:                data = cmmu->GetSCR();
1.1.1.8   root       81:                cmmu->putlogf(2, lstr("SCR  -> $%08x", data.Data()));
1.1.1.7   root       82:                break;
1.1       root       83: 
                     84:         case SSR:
                     85:                data = cmmu->GetSSR();
1.1.1.8   root       86:                cmmu->putlogf(2, lstr("SSR  -> $%08x", data.Data()));
1.1.1.7   root       87:                break;
1.1       root       88: 
                     89:         case SAR:
                     90:                data = cmmu->GetSAR();
1.1.1.8   root       91:                cmmu->putlogf(2, lstr("SAR  -> $%08x", data.Data()));
1.1.1.7   root       92:                break;
1.1       root       93: 
                     94:         case SCTR:
                     95:                data = cmmu->GetSCTR();
1.1.1.8   root       96:                cmmu->putlogf(2, lstr("SCTR -> $%08x", data.Data()));
1.1.1.7   root       97:                break;
1.1       root       98: 
                     99:         case PFSR:
                    100:                data = cmmu->GetPFSR();
1.1.1.8   root      101:                cmmu->putlogf(2, lstr("PFSR -> $%08x", data.Data()));
1.1.1.7   root      102:                break;
1.1       root      103: 
                    104:         case PFAR:
                    105:                data = cmmu->GetPFAR();
1.1.1.8   root      106:                cmmu->putlogf(2, lstr("PFAR -> $%08x", data.Data()));
1.1.1.7   root      107:                break;
1.1       root      108: 
                    109:         case SAPR:
                    110:                data = cmmu->GetSAPR();
1.1.1.8   root      111:                cmmu->putlogf(2, lstr("SAPR -> $%08x", data.Data()));
1.1.1.7   root      112:                break;
1.1       root      113: 
                    114:         case UAPR:
                    115:                data = cmmu->GetUAPR();
1.1.1.8   root      116:                cmmu->putlogf(2, lstr("UAPR -> $%08x", data.Data()));
1.1.1.7   root      117:                break;
1.1       root      118: 
                    119:         case BWP0 ... BWP7:
                    120:                // BWP は書き込み専用 (何が読めるだろうか)
1.1.1.7   root      121:                data = 0xffffffff;
1.1       root      122:                break;
                    123: 
                    124:         case CSSP:
                    125:                data = cmmu->GetCSSP();
1.1.1.8   root      126:                cmmu->putlogf(2, lstr("CSSP -> $%08x", data.Data()));
1.1.1.7   root      127:                break;
1.1       root      128: 
1.1.1.7   root      129:         case CDP0 ... CDP3:
                    130:         case CTP0 ... CTP3:
1.1       root      131:         default:
1.1.1.8   root      132:                putlog(0, "Read $%08x (NOT IMPLEMENTED)", paddr);
1.1.1.7   root      133:                data = 0xffffffff;
1.1       root      134:        }
1.1.1.7   root      135: 
                    136:        // XXX wait?
1.1.1.8   root      137:        data |= BusData::Size4;
                    138:        return data;
1.1       root      139: }
                    140: 
1.1.1.7   root      141: busdata
1.1.1.8   root      142: CMMUDevice::Write(busaddr addr, uint32 data)
1.1       root      143: {
1.1.1.8   root      144:        uint32 paddr = addr.Addr();
1.1       root      145: 
1.1.1.8   root      146:        uint32 id = (paddr >> 12) & 0xff;
1.1       root      147:        m88200 *cmmu = GetCMMU(id);
                    148:        if (cmmu == NULL) {
1.1.1.8   root      149:                putlog(3, "Write not-equipped CMMU[%u] $%08x <- $%08x",
                    150:                        id, paddr, data);
1.1       root      151:                return 0;
                    152:        }
                    153: 
1.1.1.8   root      154:        // 普通はロングワードアクセスしかしないはず。
                    155:        // m88k 専用なのでミスアラインアクセスは起きない。
                    156:        // 88200 p5-27
                    157:        uint32 size = addr.GetSize();
                    158:        if (size == 4) {
                    159:                // nop
                    160:        } else {
                    161:                if (size == 1) {
                    162:                        data |= data << 8;
                    163:                }
                    164:                data |= data << 16;
                    165:        }
                    166: 
                    167:        uint32 offset = Decoder(paddr);
1.1       root      168:        uint n;
                    169:        switch (offset) {
                    170:         case IDR:
                    171:         {
                    172:                uint32 newid = data >> 24;
                    173:                if (id != newid) {
1.1.1.6   root      174:                        // 後から ID を変更するのはサポートしない。というか実際無理では。
                    175:                        cmmu->putlogf(0, lstr(
                    176:                                "IDR  <- $%08x (change ID $%02x to $%02x; NOT SUPPORTED)",
                    177:                                data, id, newid));
1.1       root      178:                } else {
1.1.1.5   root      179:                        cmmu->putlogf(2, lstr("IDR  <- $%08x", data));
1.1       root      180:                }
1.1.1.7   root      181:                break;
1.1       root      182:         }
                    183: 
                    184:         case SCR:
                    185:                cmmu->SetSCR(data);
1.1.1.7   root      186:                break;
1.1       root      187: 
                    188:         case SSR:
1.1.1.2   root      189:                cmmu->putlogf(1, lstr("SSR  <- $%08x", data));
1.1       root      190:                cmmu->SetSSR(data);
1.1.1.7   root      191:                break;
1.1       root      192: 
                    193:         case SAR:
1.1.1.2   root      194:                cmmu->putlogf(2, lstr("SAR  <- $%08x", data));
1.1       root      195:                cmmu->SetSAR(data);
1.1.1.7   root      196:                break;
1.1       root      197: 
                    198:         case SCTR:
                    199:                cmmu->SetSCTR(data);
1.1.1.7   root      200:                break;
1.1       root      201: 
                    202:         case PFSR:
                    203:                cmmu->SetPFSR(data);
1.1.1.7   root      204:                break;
1.1       root      205: 
                    206:         case PFAR:
                    207:                cmmu->SetPFAR(data);
1.1.1.7   root      208:                break;
1.1       root      209: 
                    210:         case SAPR:
                    211:                cmmu->SetSAPR(data);
1.1.1.7   root      212:                break;
1.1       root      213: 
                    214:         case UAPR:
                    215:                cmmu->SetUAPR(data);
1.1.1.7   root      216:                break;
1.1       root      217: 
                    218:         case BWP0 ... BWP7:
                    219:                n = (offset - BWP0) / 4;
                    220:                assert(n < 8);
1.1.1.4   root      221:                cmmu->SetBWP(n, data);
1.1       root      222:                break;
                    223: 
                    224:         case CSSP:
                    225:                cmmu->SetCSSP(data);
1.1.1.7   root      226:                break;
1.1       root      227: 
1.1.1.7   root      228:         case CDP0 ... CDP3:
                    229:         case CTP0 ... CTP3:
1.1       root      230:         default:
1.1.1.8   root      231:                putlog(0, "Write $%08x <- $%08x (NOT IMPLEMENTED)", paddr, data);
1.1.1.7   root      232:                VMPANIC("not impl");
1.1       root      233:                break;
                    234:        }
1.1.1.7   root      235: 
                    236:        // wait?
1.1.1.8   root      237:        busdata r = BusData::Size4;
                    238:        return r;
1.1       root      239: }
                    240: 
1.1.1.8   root      241: // Peek1() の下請け。ロングワードで処理して後でバイトに分割するほうが楽。
1.1       root      242: uint32
1.1.1.8   root      243: CMMUDevice::Peek4(uint32 addr) const
1.1       root      244: {
                    245:        uint32 id = (addr >> 12) & 0xff;
                    246: 
                    247:        m88200 *cmmu = GetCMMU(id);
                    248:        if (cmmu == NULL) {
                    249:                return 0xffffffff;
                    250:        }
                    251: 
                    252:        uint32 offset = Decoder(addr);
                    253:        switch (offset) {
                    254:         case IDR:
                    255:                return cmmu->GetIDR();
                    256: 
                    257:         case SCR:
                    258:                return cmmu->GetSCR();
                    259: 
                    260:         case SSR:
                    261:                return cmmu->GetSSR();
                    262: 
                    263:         case SAR:
                    264:                return cmmu->GetSAR();
                    265: 
                    266:         case SCTR:
                    267:                return cmmu->GetSCTR();
                    268: 
                    269:         case PFSR:
                    270:                return cmmu->GetPFSR();
                    271: 
                    272:         case PFAR:
                    273:                return cmmu->GetPFAR();
                    274: 
                    275:         case SAPR:
                    276:                return cmmu->GetSAPR();
                    277: 
                    278:         case UAPR:
                    279:                return cmmu->GetUAPR();
                    280: 
                    281:         case BWP0 ... BWP7:
                    282:                return 0xffffffff;
                    283: 
                    284:         case CDP0 ... CDP3:
                    285:         case CTP0 ... CTP3:
                    286:                break;
                    287: 
                    288:         case CSSP:
                    289:                return cmmu->GetCSSP();
                    290: 
                    291:         default:
                    292:                break;
                    293:        }
                    294:        return 0xffffffff;
                    295: }
                    296: 
1.1.1.7   root      297: busdata
1.1.1.8   root      298: CMMUDevice::Peek1(uint32 addr)
1.1       root      299: {
1.1.1.8   root      300:        uint32 data = Peek4(addr & ~3U);
1.1       root      301:        switch (addr & 3) {
                    302:         case 0:
                    303:                return data >> 24;
                    304:         case 1:
                    305:                return (data >> 16) & 0xff;
                    306:         case 2:
                    307:                return (data >>  8) & 0xff;
                    308:         case 3:
                    309:                return data & 0xff;
1.1.1.6   root      310:         default:
                    311:                return 0xff;
1.1       root      312:        }
                    313: }

unix.superglobalmegacorp.com

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