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

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

unix.superglobalmegacorp.com

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