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

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

unix.superglobalmegacorp.com

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