Annotation of nono/vm/x68kio.cpp, revision 1.1.1.1

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: //
                      8: // X68030 のメイン空間 ($000000-$FFFFFF) 担当
                      9: //
                     10: 
                     11: #include "x68kio.h"
                     12: #include "adpcm.h"
                     13: #include "areaset.h"
                     14: #include "busio.h"
                     15: #include "config.h"
                     16: #include "crtc.h"
                     17: #include "dmac.h"
                     18: #include "fdc.h"
                     19: #include "gvram.h"
                     20: #include "mainram.h"
                     21: #include "mfp.h"
                     22: #include "opm.h"
                     23: #include "pedec.h"
                     24: #include "pio.h"
                     25: #include "pluto.h"
                     26: #include "printer.h"
                     27: #include "romemu_x68k.h"
                     28: #include "romimg_x68k.h"
                     29: #include "rp5c15.h"
                     30: #include "scc.h"
                     31: #include "spc.h"
                     32: #include "sprite.h"
                     33: #include "sram.h"
                     34: #include "sysport.h"
                     35: #include "tvram.h"
                     36: #include "videoctlr.h"
                     37: #include "vm.h"
                     38: 
                     39: // コンストラクタ
                     40: X68kIODevice::X68kIODevice()
                     41:        : inherited(OBJ_X68KIO)
                     42: {
                     43: #define ADD_DEVICE(NAME, ADDR, LEN)    \
                     44:        AddDevice(__CONCAT(p,NAME).get(), ADDR, LEN)
                     45: 
                     46: #define N(NAME, NEW_CTOR, ADDR, LEN)   do {    \
                     47:                NEWDV(NAME, NEW_CTOR);  \
                     48:                ADD_DEVICE(NAME, ADDR, LEN);    \
                     49:        } while (0)
                     50: 
                     51:        // デバイスクラス作成。
                     52:        // 初期化順の制約がない限りアドレス順。
                     53:        //                                              開始アドレス 長さ
                     54:        N(GVRAM, new GVRAMDevice(),                                     0xc00000,0x200000);
                     55:        N(PlaneVRAM, new TVRAMDevice(),                         0xe00000, 0x80000);
                     56:        N(CRTC, new BusIO_W<CRTCDevice>(),                      0xe80000,  0x2000);
                     57:        N(VideoCtlr, new VideoCtlrDevice(),                     0xe82000,  0x2000);
                     58:        N(DMAC, new DMACDevice(),                                       0xe84000,  0x2000);
                     59:        N(AreaSet, new AreaSetDevice(),                         0xe86000,  0x2000);
                     60:        N(MFP, new BusIO_EB<MFPDevice>(),                       0xe88000,  0x2000);
                     61:        N(RTC, new BusIO_EB<RP5C15Device>(),            0xe8a000,  0x2000);
                     62:        N(Printer, new PrinterDevice(),                         0xe8c000,  0x2000);
                     63:        N(Sysport,new BusIO_FB<SysportDevice>(),        0xe8e000,  0x2000);
                     64:        N(OPM, new BusIO_EB<OPMDevice>(),                       0xe90000,  0x2000);
                     65:        N(ADPCM, new BusIO_EB<ADPCMDevice>(),           0xe92000,  0x2000);
                     66:        N(FDC, new BusIO_EB<FDCDevice>(),                       0xe94000,  0x2000);
                     67:        N(SPC, new BusIO_X68kSPC<SPCDevice>(),          0xe96000,  0x2000);
                     68:        N(SCC, new BusIO_EB<SCCDevice>(),                       0xe98000,  0x2000);
                     69:        N(PPI, new BusIO_EB<PPIDevice>(),                       0xe9a000,  0x2000);
                     70:        N(PEDEC, new BusIO_EB<PEDECDevice>(),           0xe9c000,  0x2000);
                     71:        N(Pluto, new PlutoDevice(),                                     0xeac000,  0x2000);
                     72:        N(Sprite, new SpriteDevice(),                           0xeb0000, 0x10000);
                     73:        N(SRAM, new SRAMDevice(),                                       0xed0000,  0x4000);
                     74:        N(CGROM, new CGROMDevice(),                                     0xf00000, 0xc0000);
                     75:        if (gConfig->Find("iplrom2-image").AsString().empty()) {
                     76:                NEWDV(IPLROM2, new ROM30EmuDevice());
                     77:        } else {
                     78:                NEWDV(IPLROM2, new IPLROM2Device());
                     79:        }
                     80:        ADD_DEVICE(IPLROM2,                                                     0xfc0000, 0x20000);
                     81:        N(IPLROM1, new IPLROM1Device(),                         0xfe0000, 0x20000);
                     82: }
                     83: 
                     84: // デストラクタ
                     85: X68kIODevice::~X68kIODevice()
                     86: {
                     87: }
                     88: 
                     89: // 初期化
                     90: bool
                     91: X68kIODevice::Init()
                     92: {
                     93:        if (inherited::Init() == false) {
                     94:                return false;
                     95:        }
                     96: 
                     97:        auto buserr = GetBusErrDevice();
                     98:        auto mainram = GetMainRAMDevice();
                     99: 
                    100:        // RAM のみ RamDevice::Init() で ram_size が決定してから行う。
                    101:        for (int i = 0; i < mainram->GetSize() / 8192; i++) {
                    102:                table[i] = mainram;
                    103:        }
                    104: 
                    105:        // 必要なデバイスは全部埋めたので、この時点で nullptr なエントリを
                    106:        // BusErr に差し替える。
                    107:        for (auto&& d : table) {
                    108:                if (d == nullptr) {
                    109:                        d = buserr;
                    110:                }
                    111:        }
                    112: 
                    113:        // デバッグ表示
                    114:        if (0) {
                    115:                for (int i = 1536; i < table.size(); i++) {
                    116:                        printf("[%3d] $%06x ", i, i * 8192);
                    117:                        assert(table[i]);
                    118:                        printf("%s\n", table[i]->GetName().c_str());
                    119:                }
                    120:        }
                    121: 
                    122:        return true;
                    123: }
                    124: 
                    125: // デバイステーブルに dev を追加する。
                    126: void
                    127: X68kIODevice::AddDevice(IODevice *dev, uint devaddr, uint devlen)
                    128: {
                    129:        int idx = devaddr / 8192;
                    130:        for (int i = idx; i < idx + (devlen + 8191) /  8192; i++) {
                    131:                // 重複するケースは未対応
                    132:                assertmsg(table[i] == nullptr, "X68kIODevice.AddDevice '%s'",
                    133:                        table[i]->GetName().c_str());
                    134: 
                    135:                table[i] = dev;
                    136:        }
                    137: }
                    138: 
                    139: // アドレス addr に対応する IODevice* を返す。
                    140: // addr は事前に 24bit マスクしてあるもの。
                    141: inline IODevice *
                    142: X68kIODevice::SearchDevice(uint32 addr) const
                    143: {
                    144:        uint idx = addr / 8192;
                    145:        __assume(idx < 2048);
                    146:        return table[idx];
                    147: }
                    148: 
                    149: uint64
                    150: X68kIODevice::Read8(uint32 addr)
                    151: {
                    152:        addr &= 0x00ffffff;
                    153:        IODevice *d = SearchDevice(addr);
                    154:        return d->Read8(addr);
                    155: }
                    156: 
                    157: uint64
                    158: X68kIODevice::Read16(uint32 addr)
                    159: {
                    160:        addr &= 0x00ffffff;
                    161:        IODevice *d = SearchDevice(addr);
                    162:        return d->Read16(addr);
                    163: }
                    164: 
                    165: uint64
                    166: X68kIODevice::Read32(uint32 addr)
                    167: {
                    168:        addr &= 0x00ffffff;
                    169:        IODevice *d = SearchDevice(addr);
                    170:        return d->Read32(addr);
                    171: }
                    172: 
                    173: uint64
                    174: X68kIODevice::Write8(uint32 addr, uint32 data)
                    175: {
                    176:        addr &= 0x00ffffff;
                    177:        IODevice *d = SearchDevice(addr);
                    178:        return d->Write8(addr, data);
                    179: }
                    180: 
                    181: uint64
                    182: X68kIODevice::Write16(uint32 addr, uint32 data)
                    183: {
                    184:        addr &= 0x00ffffff;
                    185:        IODevice *d = SearchDevice(addr);
                    186:        return d->Write16(addr, data);
                    187: }
                    188: 
                    189: uint64
                    190: X68kIODevice::Write32(uint32 addr, uint32 data)
                    191: {
                    192:        addr &= 0x00ffffff;
                    193:        IODevice *d = SearchDevice(addr);
                    194:        return d->Write32(addr, data);
                    195: }
                    196: 
                    197: uint64
                    198: X68kIODevice::Peek8(uint32 addr)
                    199: {
                    200:        addr &= 0x00ffffff;
                    201:        IODevice *d = SearchDevice(addr);
                    202:        return d->Peek8(addr);
                    203: }
                    204: 
                    205: // このアドレスを担当する次段の IODevice を返す (IOContainerDevice 用)
                    206: IODevice *
                    207: X68kIODevice::GetDevice(uint32 addr) const
                    208: {
                    209:        return SearchDevice(addr & 0x00ffffff);
                    210: }
                    211: 
                    212: // ブートページを切り替える。
                    213: // (VM_X68030::SwitchBootPage() の下請け)
                    214: void
                    215: X68kIODevice::SwitchBootPage(bool isrom)
                    216: {
                    217:        IODevice *ram;
                    218:        IODevice *rom;
                    219: 
                    220:        if (isrom) {
                    221:                // 0x000000 からの  64KB ( 8エントリ)、
                    222:                // 0xfe0000 からの 128KB (16エントリ) のどちらも IPLROM0 が担当する。
                    223:                ram = GetIPLROM0Device();
                    224:                rom = GetIPLROM0Device();
                    225:        } else {
                    226:                // 0x000000 からの  64KB ( 8エントリ) に RAM を見せる。
                    227:                // 0xfe0000 からの 128KB (16エントリ) に IPLROM1 を見せる。
                    228:                ram = GetMainRAMDevice();
                    229:                rom = GetIPLROM1Device();
                    230:        }
                    231: 
                    232:        for (int i = 0; i < 8; i++) {
                    233:                table[i] = ram;
                    234:        }
                    235:        for (int i = 0; i < 16; i++) {
                    236:                table[table.size() - 16 + i] = rom;
                    237:        }
                    238: }

unix.superglobalmegacorp.com

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