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

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

unix.superglobalmegacorp.com

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