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

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: 
1.1.1.3   root       11: // IODevice
                     12: //   +-- MainbusBaseDevice (InitMainbus() と FC アクセスを持つ)
                     13: //   |    +-- MainbusDevice (これがメインバス、システムに1つ)
                     14: //   |    |    +-- Mainbus24Device (上位8ビットがテーブルで表せるメインバス)
                     15: //   |    |    |    +-- LunaMainbus
                     16: //   |    |    |    |    +-- Luna1Mainbus
                     17: //   |    |    |    |    +-- Luna88kMainbus
                     18: //   |    |    |    +-- NewsMainbus
                     19: //   |    |    +-- X68kMainbus
                     20: //   |    |
                     21: //   |    |  +--------------+
                     22: //   |    +--| X68kIODevice | (FC を受け取るため)
                     23: //   |       +--------------+
                     24: //   |
                     25: //   +-- XPbusDevice
                     26: 
1.1       root       27: #include "x68kio.h"
                     28: #include "adpcm.h"
                     29: #include "areaset.h"
1.1.1.3   root       30: #include "bankram.h"
1.1       root       31: #include "busio.h"
                     32: #include "config.h"
                     33: #include "crtc.h"
                     34: #include "dmac.h"
1.1.1.3   root       35: #include "extarea.h"
1.1       root       36: #include "fdc.h"
                     37: #include "gvram.h"
1.1.1.2   root       38: #include "mainbus.h"
1.1       root       39: #include "mainram.h"
                     40: #include "mfp.h"
1.1.1.5 ! root       41: #include "monitor.h"
1.1.1.3   root       42: #include "mpu.h"
1.1.1.2   root       43: #include "nereid.h"
1.1       root       44: #include "opm.h"
                     45: #include "pedec.h"
                     46: #include "pio.h"
                     47: #include "pluto.h"
                     48: #include "printer.h"
                     49: #include "romemu_x68k.h"
                     50: #include "romimg_x68k.h"
                     51: #include "rp5c15.h"
                     52: #include "scc.h"
                     53: #include "spc.h"
                     54: #include "sprite.h"
                     55: #include "sram.h"
                     56: #include "sysport.h"
                     57: #include "tvram.h"
                     58: #include "videoctlr.h"
1.1.1.3   root       59: #include "windrv.h"
                     60: #include <algorithm>
1.1       root       61: 
                     62: // コンストラクタ
                     63: X68kIODevice::X68kIODevice()
                     64:        : inherited(OBJ_X68KIO)
                     65: {
1.1.1.5 ! root       66:        map_monitor = gMonitorManager->Regist(ID_SUBWIN_X68KIO, this);
        !            67:        map_monitor->func = ToMonitorCallback(&X68kIODevice::MonitorUpdate);
        !            68:        map_monitor->SetSize(73, 1 + 32);
        !            69:        map_monitor->SetMaxHeight(1 + 256);
1.1.1.2   root       70: 
1.1.1.3   root       71:        // エリアセットは実質ここが担当しているので、モニタもここ。
1.1.1.5 ! root       72:        area_monitor = gMonitorManager->Regist(ID_MONITOR_AREASET, this);
        !            73:        area_monitor->func = ToMonitorCallback(&X68kIODevice::MonitorUpdateAreaset);
        !            74:        area_monitor->SetSize(32, 6);
1.1.1.3   root       75: 
                     76:        cut_fc2 = (gConfig->Find("x68k-cut-fc2").AsInt() != 0);
                     77: 
1.1       root       78: #define ADD_DEVICE(NAME, ADDR, LEN)    \
                     79:        AddDevice(__CONCAT(p,NAME).get(), ADDR, LEN)
                     80: 
                     81: #define N(NAME, NEW_CTOR, ADDR, LEN)   do {    \
                     82:                NEWDV(NAME, NEW_CTOR);  \
                     83:                ADD_DEVICE(NAME, ADDR, LEN);    \
                     84:        } while (0)
                     85: 
1.1.1.3   root       86:        NEWDV(BusErr, new BusErrDevice());
                     87:        NEWDV(MainRAM, new MainRAMDevice());
                     88:        NEWDV(IPLROM0, new IPLROM0Device());
                     89: 
1.1       root       90:        // デバイスクラス作成。
                     91:        // 初期化順の制約がない限りアドレス順。
                     92:        //                                              開始アドレス 長さ
                     93:        N(GVRAM, new GVRAMDevice(),                                     0xc00000,0x200000);
                     94:        N(PlaneVRAM, new TVRAMDevice(),                         0xe00000, 0x80000);
1.1.1.3   root       95:        N(CRTC, new CRTCDevice(),                                       0xe80000,  0x2000);
1.1       root       96:        N(VideoCtlr, new VideoCtlrDevice(),                     0xe82000,  0x2000);
                     97:        N(DMAC, new DMACDevice(),                                       0xe84000,  0x2000);
1.1.1.4   root       98:        N(AreaSet, new BusIO_EB<AreaSetDevice>(),       0xe86000,  0x2000);
1.1       root       99:        N(MFP, new BusIO_EB<MFPDevice>(),                       0xe88000,  0x2000);
                    100:        N(RTC, new BusIO_EB<RP5C15Device>(),            0xe8a000,  0x2000);
1.1.1.4   root      101:        N(Printer, new BusIO_EB<PrinterDevice>(),       0xe8c000,  0x2000);
1.1       root      102:        N(Sysport,new BusIO_FB<SysportDevice>(),        0xe8e000,  0x2000);
                    103:        N(OPM, new BusIO_EB<OPMDevice>(),                       0xe90000,  0x2000);
                    104:        N(ADPCM, new BusIO_EB<ADPCMDevice>(),           0xe92000,  0x2000);
                    105:        N(FDC, new BusIO_EB<FDCDevice>(),                       0xe94000,  0x2000);
                    106:        N(SPC, new BusIO_X68kSPC<SPCDevice>(),          0xe96000,  0x2000);
                    107:        N(SCC, new BusIO_EB<SCCDevice>(),                       0xe98000,  0x2000);
                    108:        N(PPI, new BusIO_EB<PPIDevice>(),                       0xe9a000,  0x2000);
                    109:        N(PEDEC, new BusIO_EB<PEDECDevice>(),           0xe9c000,  0x2000);
1.1.1.3   root      110:        // Windrv はデバイスは常に作成し、マップするかどうかは設定による。
1.1.1.4   root      111:        NEWDV(Windrv, new BusIO_B<WindrvDevice>());
1.1.1.3   root      112:        if (WindrvDevice::IsWindrv()) {
                    113:                ADD_DEVICE(Windrv,                                              0xe9e000,  0x2000);
                    114:        }
1.1       root      115:        N(Pluto, new PlutoDevice(),                                     0xeac000,  0x2000);
1.1.1.3   root      116:        N(ExtArea, new ExtAreaDevice(),                         0xeae000,  0x2000);
1.1       root      117:        N(Sprite, new SpriteDevice(),                           0xeb0000, 0x10000);
1.1.1.2   root      118:        // Nereid はこの時点ではデバイスの追加のみ。Init() 参照。
                    119:        NEWDV(Nereid, new NereidDevice());              //      0xece000,  0x2000
1.1       root      120:        N(SRAM, new SRAMDevice(),                                       0xed0000,  0x4000);
                    121:        N(CGROM, new CGROMDevice(),                                     0xf00000, 0xc0000);
                    122:        if (gConfig->Find("iplrom2-image").AsString().empty()) {
                    123:                NEWDV(IPLROM2, new ROM30EmuDevice());
                    124:        } else {
                    125:                NEWDV(IPLROM2, new IPLROM2Device());
                    126:        }
                    127:        ADD_DEVICE(IPLROM2,                                                     0xfc0000, 0x20000);
                    128:        N(IPLROM1, new IPLROM1Device(),                         0xfe0000, 0x20000);
                    129: }
                    130: 
                    131: // デストラクタ
                    132: X68kIODevice::~X68kIODevice()
                    133: {
                    134: }
                    135: 
1.1.1.3   root      136: // メインバスの初期化
1.1       root      137: bool
1.1.1.3   root      138: X68kIODevice::InitMainbus()
1.1       root      139: {
1.1.1.3   root      140:        auto buserr = pBusErr.get();
                    141:        auto mainram = dynamic_cast<MainRAMDevice*>(pMainRAM.get());
1.1       root      142: 
1.1.1.3   root      143:        // RAM は容量が確定した後のここで配置。
1.1       root      144:        for (int i = 0; i < mainram->GetSize() / 8192; i++) {
1.1.1.3   root      145:                sdevice[i] = mainram;
1.1       root      146:        }
                    147: 
1.1.1.2   root      148:        // Nereid は1枚でもボードがある時だけメモリ空間に追加する。
                    149:        // Nereid が1枚もない場合でもモニタやログ(この場合のログは起動時にどれが
                    150:        // 有効とか無効と判断したことを表示するもの)のためデバイス自体は常に存在。
                    151:        auto nereid = GetNereidDevice();
                    152:        if (nereid->IsInstalled()) {
                    153:                ADD_DEVICE(Nereid, 0xece000, 0x2000);
1.1.1.3   root      154: 
                    155:                // バンク領域もバンクメモリが有効な場合のみ追加する。
                    156:                // #0 が $ee0000、
                    157:                // #1 が $ef0000 固定にしている。
                    158:                for (int i = 0; i < 2; i++) {
                    159:                        auto bank = gMainApp.FindObject<BankRAMDevice>(OBJ_BANKRAM(i));
                    160:                        if (bank != NULL && bank->GetSize() > 0) {
                    161:                                AddDevice(bank, 0xee0000 + i * 0x010000, 0x010000);
                    162:                        }
                    163:                }
1.1.1.2   root      164:        }
                    165: 
1.1       root      166:        // 必要なデバイスは全部埋めたので、この時点で nullptr なエントリを
                    167:        // BusErr に差し替える。
1.1.1.3   root      168:        for (auto&& d : sdevice) {
1.1       root      169:                if (d == nullptr) {
                    170:                        d = buserr;
                    171:                }
                    172:        }
                    173: 
1.1.1.3   root      174:        // ユーザ空間にコピー。
                    175:        // 00'0000 - BF'FFFF: S U : RAM
                    176:        // C0'0000 - E7'FFFF: S - : GVRAM/TVRAM
                    177:        // E8'0000 - EB'FFFF: S - : I/O 空間
                    178:        // EC'0000 - EC'FFFF: S U : ユーザ I/O 空間
                    179:        // ED'0000 - EF'FFFF: S - : I/O 空間
                    180:        // F0'0000 - FF'FFFF: S - : ROM
                    181:        SetUdevice(0x000000, 0xbfffff, true);
                    182:        SetUdevice(0xc00000, 0xebffff, false);
                    183:        SetUdevice(0xec0000, 0xecffff, true);
                    184:        SetUdevice(0xed0000, 0xffffff, false);
                    185: 
                    186:        // ユーザ空間も nullptr をチェック。
                    187:        assert(std::all_of(udevice.begin(), udevice.end(),
                    188:                [](IODevice *d) { return d != nullptr; }));
                    189: 
1.1       root      190:        // デバッグ表示
                    191:        if (0) {
1.1.1.3   root      192:                for (int i = 1536; i < sdevice.size(); i++) {
1.1.1.4   root      193:                        printf("[%3u] $%06x ", i, i * 8192);
1.1.1.3   root      194:                        assert(sdevice[i]);
                    195:                        assert(udevice[i]);
                    196:                        printf("S:%-8s U:%s\n",
                    197:                                sdevice[i]->GetName().c_str(),
                    198:                                udevice[i]->GetName().c_str());
1.1       root      199:                }
                    200:        }
                    201: 
                    202:        return true;
                    203: }
                    204: 
1.1.1.3   root      205: // アドレス start から end (を含む) までのユーザ空間を作成する。
                    206: // accessible true ならユーザアクセス可能 (スーパーバイザ空間をコピー)。
                    207: // false なら BusErr で埋める。
                    208: void
                    209: X68kIODevice::SetUdevice(uint32 startaddr, uint32 endaddr, bool accessible)
                    210: {
                    211:        assert(startaddr < endaddr);
                    212:        assert(((endaddr + 1) & 0x1fff) == 0);
1.1.1.4   root      213:        uint start = startaddr / 8192;
                    214:        uint end = (endaddr + 1) / 8192;
1.1.1.3   root      215: 
                    216:        // MPU の FC2 ピンカットの動作は本来 MPU 側を加工すべきだが、
                    217:        // MPU アクセスのほうが圧倒的に多いので影響の少ない DMAC 側で処理する。
                    218: 
                    219:        // FC2 ピンカットする前の情報を DMAC に展開。
                    220:        auto dmac = dynamic_cast<DMACDevice*>(pDMAC.get());
                    221:        dmac->SetUdevice(start, end, accessible);
                    222: 
                    223:        // FC2 ピンカットなら全域がユーザアクセス可能。
                    224:        if (cut_fc2) {
                    225:                accessible = true;
                    226:        }
                    227: 
                    228:        if (accessible) {
                    229:                memcpy(&udevice[start], &sdevice[start],
                    230:                        (end - start) * sizeof(udevice[0]));
                    231:        } else {
                    232:                auto buserr = pBusErr.get();
                    233:                for (int i = start; i < end; i++) {
                    234:                        udevice[i] = buserr;
                    235:                }
                    236:        }
                    237: }
                    238: 
                    239: // デバイステーブル sdevice に dev を追加する。
1.1       root      240: void
                    241: X68kIODevice::AddDevice(IODevice *dev, uint devaddr, uint devlen)
                    242: {
1.1.1.4   root      243:        uint idx = devaddr / 8192;
1.1       root      244:        for (int i = idx; i < idx + (devlen + 8191) /  8192; i++) {
                    245:                // 重複するケースは未対応
1.1.1.3   root      246:                assertmsg(sdevice[i] == nullptr, "X68kIODevice.AddDevice '%s'",
                    247:                        sdevice[i]->GetName().c_str());
1.1       root      248: 
1.1.1.3   root      249:                sdevice[i] = dev;
1.1       root      250:        }
                    251: }
                    252: 
1.1.1.3   root      253: // アドレス super:addr に対応する IODevice* を返す。
1.1       root      254: // addr は事前に 24bit マスクしてあるもの。
                    255: inline IODevice *
1.1.1.3   root      256: X68kIODevice::Decoder(bool super, uint32 addr) const
1.1       root      257: {
                    258:        uint idx = addr / 8192;
1.1.1.3   root      259:        if (super) {
                    260:                return sdevice[idx];
                    261:        } else {
                    262:                return udevice[idx];
                    263:        }
1.1       root      264: }
                    265: 
1.1.1.3   root      266: // 回路図より CIIN は以下の通り。
                    267: //
                    268: // FC1 ---------|
                    269: // ______       |OR ---o|&      ____
                    270: // DSACK0 --o|>-|       |&o---- CIIN
                    271: // __                   |&
                    272: // AS -----------------o|&
                    273: //
                    274: // __     ___                 ____
                    275: // AS FC1 DS0 : DS0 FC1|DS0 : CIIN
                    276: //  L   0   H :  L     L    :  L   (データ空間 & 16ビットポート)
                    277: //  L   0   L :  H     H    :  H
                    278: //  L   1   H :  L     H    :  H
                    279: //  L   1   L :  H     H    :  H
                    280: 
                    281: inline void
                    282: X68kIODevice::CheckCI(busaddr addr)
1.1       root      283: {
1.1.1.3   root      284:        // 16ビットポートはメインメモリ、GVRAM、TVRAM、ROM を除いた部分なので
                    285:        // 0xe80000 .. 0xefffff かな。
1.1.1.4   root      286:        busaddr cimask = busaddr(0xf80000) | BusAddr::D;
                    287:        busaddr data16 = busaddr(0xe80000) | BusAddr::D;
1.1.1.3   root      288:        if ((addr.Get() & cimask.Get()) == data16.Get()) {
                    289:                mpu->SetCI();
                    290:        }
1.1       root      291: }
                    292: 
1.1.1.3   root      293: busdata
1.1.1.4   root      294: X68kIODevice::Read(busaddr addr)
1.1       root      295: {
1.1.1.4   root      296:        addr &= 0x00ffffff;
                    297:        CheckCI(addr);
1.1.1.3   root      298: 
1.1.1.4   root      299:        IODevice *d = Decoder(addr.IsSuper(), addr.Addr());
                    300:        busdata bd = d->Read(addr);
                    301:        putlog(2, "Read  $%06x -> $%0*x",
                    302:                addr.Addr(), addr.GetSize() * 2, bd.Data());
1.1.1.3   root      303:        return bd;
1.1       root      304: }
                    305: 
1.1.1.3   root      306: busdata
1.1.1.4   root      307: X68kIODevice::Write(busaddr addr, uint32 data)
1.1       root      308: {
1.1.1.4   root      309:        addr &= 0x00ffffff;
                    310:        CheckCI(addr);
1.1.1.3   root      311: 
1.1.1.4   root      312:        IODevice *d = Decoder(addr.IsSuper(), addr.Addr());
                    313:        putlog(2, "Write $%06x <- $%0*x", addr.Addr(), addr.GetSize() * 2, data);
                    314:        return d->Write(addr, data);
1.1       root      315: }
                    316: 
1.1.1.3   root      317: busdata
1.1.1.4   root      318: X68kIODevice::Peek1(uint32 addr)
1.1       root      319: {
1.1.1.4   root      320:        addr &= 0x00ffffff;
1.1.1.3   root      321: 
1.1.1.4   root      322:        IODevice *d = Decoder(true, addr);
                    323:        return d->Peek1(addr);
1.1.1.3   root      324: }
                    325: 
1.1.1.4   root      326: bool
                    327: X68kIODevice::Poke1(uint32 addr, uint32 data)
1.1.1.3   root      328: {
1.1.1.4   root      329:        addr &= 0x00ffffff;
1.1.1.3   root      330: 
1.1.1.4   root      331:        IODevice *d = Decoder(true, addr);
                    332:        return d->Poke1(addr, data);
1.1       root      333: }
                    334: 
1.1.1.2   root      335: void
                    336: X68kIODevice::MonitorUpdate(Monitor *, TextScreen& screen)
                    337: {
                    338:        screen.Clear();
                    339: 
                    340:        // pos が表示開始位置(0-)
                    341:        int pos = (int)screen.userdata;
                    342: 
1.1.1.3   root      343:        // ヘッダは常に描く
                    344:        screen.Clear();
1.1.1.2   root      345:        for (int i = 0; i < 8; i++) {
                    346:                screen.Print(10 + i * 8, 0, "+$%04x", i * 0x2000);
                    347:        }
                    348: 
1.1.1.3   root      349:        // 012345678901234567890
                    350:        // $00'0000: 1234567
                    351: 
1.1.1.4   root      352:        uint idx = pos * 8;
1.1.1.3   root      353:        for (int y = 1, end = screen.GetRow(); y < end; y++) {
                    354:                screen.Print(0, y, "$%02x'0000:", (idx * 0x2000) >> 16);
1.1.1.2   root      355:                for (int i = 0; i < 8; i++) {
1.1.1.3   root      356:                        auto sdev = sdevice[idx];
                    357:                        auto udev = udevice[idx];
                    358:                        auto pair = MainbusBaseDevice::FormatDevName(sdev);
                    359:                        TA attr;
                    360:                        if (sdev != udev) {
                    361:                                // スーパーバイザ空間は太字とかにして区別する。
                    362:                                attr = TA::Bold;
                    363:                        } else {
                    364:                                // 両方からアクセス可能 (かそもそもバスエラー)。
                    365:                                attr = pair.second;
                    366:                        }
1.1.1.2   root      367:                        const std::string& name = pair.first;
                    368:                        screen.Print(10 + i * 8, y, attr, "%s", name.c_str());
                    369:                        idx++;
                    370:                }
                    371:        }
                    372: }
                    373: 
1.1       root      374: // ブートページを切り替える。
1.1.1.3   root      375: // X68kMainbus から呼ばれるが実際はこっちがメイン。
1.1       root      376: void
                    377: X68kIODevice::SwitchBootPage(bool isrom)
                    378: {
                    379:        IODevice *ram;
                    380:        IODevice *rom;
                    381: 
1.1.1.3   root      382:        if (gMainApp.human_mode) {
                    383:                // Human モードではブートページを RAM に見せる。
                    384:                // 今のところ。
                    385:                return;
                    386:        }
                    387: 
                    388:        // 共通処理
                    389:        inherited::SwitchBootPage(isrom);
                    390: 
1.1       root      391:        if (isrom) {
                    392:                // 0x000000 からの  64KB ( 8エントリ)、
                    393:                // 0xfe0000 からの 128KB (16エントリ) のどちらも IPLROM0 が担当する。
                    394:                ram = GetIPLROM0Device();
                    395:                rom = GetIPLROM0Device();
                    396:        } else {
                    397:                // 0x000000 からの  64KB ( 8エントリ) に RAM を見せる。
                    398:                // 0xfe0000 からの 128KB (16エントリ) に IPLROM1 を見せる。
                    399:                ram = GetMainRAMDevice();
                    400:                rom = GetIPLROM1Device();
                    401:        }
                    402: 
                    403:        for (int i = 0; i < 8; i++) {
1.1.1.3   root      404:                sdevice[i] = ram;
1.1       root      405:        }
                    406:        for (int i = 0; i < 16; i++) {
1.1.1.3   root      407:                sdevice[sdevice.size() - 16 + i] = rom;
                    408:        }
                    409: }
                    410: 
                    411: // エリアセット設定
                    412: void
                    413: X68kIODevice::SetAreaset(uint8 arealimit_)
                    414: {
                    415:        arealimit = arealimit_;
                    416: 
                    417:        // $000000 から (設定値 + 1) * 8KB をスーパーバイザ領域にする。
                    418:        // $00 なら $000000 から $001FFF まで (8KB)。
                    419:        // $ff なら $000000 から $01FFFF まで (2MB)。
                    420:        // X68030 なのでメモリは最低でも 4MB あるので上限チェックは不要。
1.1.1.4   root      421:        uint end = (arealimit + 1);
1.1.1.3   root      422:        SetUdevice(0x00'0000, end * 8192 - 1, false);
                    423:        SetUdevice(end * 8192, 0x20'0000 - 1, true);
                    424: }
                    425: 
                    426: // 拡張エリアセット取得
                    427: uint8
1.1.1.4   root      428: X68kIODevice::GetExtarea(uint offset) const
1.1.1.3   root      429: {
1.1.1.4   root      430:        if (offset < extarea.size()) {
1.1.1.3   root      431:                return extarea[offset];
                    432:        }
                    433:        // ?
                    434:        return 0xff;
                    435: }
                    436: 
                    437: // 拡張エリアセット設定
                    438: void
1.1.1.4   root      439: X68kIODevice::SetExtarea(uint offset, uint8 data)
1.1.1.3   root      440: {
1.1.1.4   root      441:        if (offset < extarea.size()) {
1.1.1.3   root      442:                extarea[offset] = data;
                    443:        }
                    444: 
                    445:        // [0] $200000 .. $3fffff (2MB)
                    446:        // [1] $400000 .. $5fffff
                    447:        // [2] $600000 .. $7fffff
                    448:        // [3] $800000 .. $9fffff
                    449:        // [4] $a00000 .. $bfffff
                    450:        //
                    451:        // +----+----+----+----+----+----+----+----+
                    452:        // | S7 | S6 | S5 | S4 | S3 | S2 | S1 | S0 |
                    453:        // +----+----+----+----+----+----+----+----+
                    454:        //
                    455:        // S0 は +$000000 〜 +$03ffff (256KB、32エントリ)
                    456:        // S1 は +$040000 〜 +$07ffff
                    457:        // S2 は +$080000 〜 +$0bffff
                    458:        // S3 は +$0c0000 〜 +$0fffff
                    459:        // S4 は +$100000 〜 +$13ffff
                    460:        // S5 は +$140000 〜 +$17ffff
                    461:        // S6 は +$180000 〜 +$1bffff
                    462:        // S7 は +$1c0000 〜 +$1fffff
                    463:        //
                    464:        // %1 ならスーパーバイザ保護 (ユーザアクセス不可)。
                    465: 
                    466:        uint32 addr = (offset + 1) * 0x20'0000;
                    467:        data = ~data;
                    468:        for (int i = 0; i < 8; i++) {
                    469:                bool u = (data & 1);
                    470:                SetUdevice(addr, addr + 0x04'0000 - 1, u);
                    471: 
                    472:                data >>= 1;
                    473:                addr += 0x04'0000;
                    474:        }
                    475: }
                    476: 
                    477: // エリアセットと拡張エリアセットのモニタ。
                    478: void
                    479: X68kIODevice::MonitorUpdateAreaset(Monitor *, TextScreen& screen)
                    480: {
1.1.1.4   root      481:        uint areaend;
1.1.1.3   root      482: 
                    483:        screen.Clear();
                    484: 
                    485:        // エリアセット
                    486:        areaend = (arealimit + 1) * 8192;
                    487:        screen.Print(0, 0, "Areaset    $%02x  $000000-$%06x",
                    488:                arealimit, areaend);
                    489: 
                    490:        // 拡張エリアセット
                    491:        for (int i = 0; i < extarea.size(); i++) {
                    492:                uint8 data = GetExtarea(i);
1.1.1.4   root      493:                screen.Print(0, i + 1, "Extarea[%u] $%02x  $%06x", i, data,
1.1.1.3   root      494:                        (i + 1) * 0x20'0000);
                    495:                for (int j = 0; j < 8; j++) {
                    496:                        screen.Putc(24 + j, i + 1, (((int8)data < 0) ? 'S' : '-'));
                    497:                        data <<= 1;
                    498:                }
1.1       root      499:        }
                    500: }

unix.superglobalmegacorp.com

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