Annotation of nono/vm/mpu680x0.cpp, revision 1.1.1.11

1.1       root        1: //
                      2: // nono
1.1.1.2   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: // MPU (m680x0)
                      8: 
                      9: #include "mpu680x0.h"
                     10: #include "config.h"
1.1.1.10  root       11: #include "m68030bus.h"
1.1.1.2   root       12: #include "m68030excep.h"
1.1       root       13: #include "mainapp.h"
1.1.1.10  root       14: #include "uimessage.h"
1.1       root       15: #include "vm.h"
                     16: #include <math.h>
                     17: 
                     18: // コンストラクタ
1.1.1.8   root       19: MPU680x0Device::MPU680x0Device()
1.1.1.9   root       20:        : inherited("MPU(68030)")
1.1       root       21: {
1.1.1.8   root       22:        cpu = m68030_init();
1.1       root       23: 
1.1.1.5   root       24:        // イベントコールバック設定
1.1.1.8   root       25:        event.SetName("MPU");
1.1.1.5   root       26:        event.func = (DeviceCallback_t)&MPU680x0Device::Callback;
1.1.1.4   root       27: 
1.1.1.9   root       28:        // レジスタモニター
                     29:        reg_monitor.func = (MonitorCallback_t)&MPU680x0Device::MonitorUpdateReg;
                     30:        reg_monitor.SetSize(79, 16);
                     31:        reg_monitor.Regist(ID_MONITOR_MPUREG);
                     32: 
                     33:        // ATC モニター
                     34:        atc_monitor.func = (MonitorCallback_t)&MPU680x0Device::MonitorUpdateATC;
                     35: #if !defined(ATC_SINGLE)
                     36:        atc_monitor.SetSize(131, m68030ATCTable::LINES + 3);
                     37: #else
                     38:        atc_monitor.SetSize(31, 24);
                     39: #endif
                     40:        atc_monitor.Regist(ID_MONITOR_MPUATC);
1.1       root       41: }
                     42: 
                     43: // デストラクタ
                     44: MPU680x0Device::~MPU680x0Device()
                     45: {
                     46: }
                     47: 
                     48: bool
                     49: MPU680x0Device::Init()
                     50: {
1.1.1.5   root       51:        // 親クラス
                     52:        if (inherited::Init() == false) {
                     53:                return false;
                     54:        }
                     55:        // MPU クロックは親 Init() で読み込んで、ここで cpu にセットする
1.1.1.7   root       56:        m68030_set_clockspeed(cpu, clock_khz);
1.1.1.5   root       57:        // 割り込み時のディレイ
                     58:        intdelay = cpu->Cycle2Vtime(4);
                     59: 
1.1       root       60:        // FPU (6888x)
1.1.1.2   root       61:        if (gMainApp.GetVMType() == VMTYPE_LUNA1) {
1.1       root       62:                // LUNA は 68881 固定 (設定は見ない)
                     63:                cpu->has_fpu = 1;
                     64:        } else {
                     65:                // X68k は設定による
1.1.1.2   root       66:                const ConfigItem& item = gConfig->Find("mpu-has-fpu");
1.1       root       67:                cpu->has_fpu = item.AsInt();
                     68:                if (cpu->has_fpu < 0 || cpu->has_fpu > 2) {
                     69:                        item.Err();
                     70:                        return false;
                     71:                }
                     72:        }
                     73: 
1.1.1.10  root       74:        cpu->halt_callback = &MPU680x0Device::HaltCallback;
                     75:        cpu->halt_arg = NULL;
                     76: 
1.1       root       77:        return true;
                     78: }
                     79: 
1.1.1.8   root       80: bool
                     81: MPU680x0Device::PowerOn()
                     82: {
                     83:        m68030_power_on(cpu);
                     84:        return true;
                     85: }
                     86: 
                     87: void
                     88: MPU680x0Device::ResetHard()
                     89: {
                     90:        // リセット例外
                     91:        m68030_request_reset_exception(cpu);
                     92: }
                     93: 
1.1.1.5   root       94: // イベントコールバック
                     95: // ev.code は
                     96: // 0x0 〜 0x7: 新しい割り込みレベルを通知 (0-7)
1.1       root       97: void
1.1.1.5   root       98: MPU680x0Device::Callback(Event& ev)
1.1       root       99: {
1.1.1.8   root      100:        int level = ev.code;
                    101:        m68030_interrupt(cpu, level);
1.1       root      102: }
                    103: 
1.1.1.5   root      104: // MPU を vtime [nsec] 分実行する。
                    105: // 戻り値は outer フラグ。
1.1       root      106: uint32
1.1.1.5   root      107: MPU680x0Device::Run(uint32 vtime)
1.1       root      108: {
1.1.1.5   root      109:        return m68030_run(cpu, vtime);
1.1       root      110: }
                    111: 
1.1.1.5   root      112: // 現在の仮想時刻 [nsec] を取得する
                    113: uint64
1.1.1.6   root      114: MPU680x0Device::GetVirtTime() const
1.1       root      115: {
1.1.1.5   root      116:        return m68030_get_vtime(cpu);
1.1       root      117: }
                    118: 
1.1.1.5   root      119: // 割り込みレベルが変わったことを MPU に通知。
1.1       root      120: void
1.1.1.5   root      121: MPU680x0Device::Interrupt(int level)
1.1       root      122: {
1.1.1.5   root      123:        assertmsg(0 <= level && level <= 7, "level=%d", level);
                    124: 
                    125:        // 外部デバイスが 68030 の IPL0-2 をアサートしてから、68030 がそれを
                    126:        // 認識(確定)するのに 2クロックかかる。ここでレベルを比較して割り込みを
                    127:        // 上げる場合は /IPEND をアサートする。
                    128:        // そこからさらに2クロック後以降の命令境界で割り込みを受け付ける(?)
                    129:        // らしい?
                    130:        // この 4クロック待つところはイベントスケジューラがある VM 側で担当する。
                    131:        // 本来、レベル比較はここから2クロック後に行われるはずだが、ちょっと省略。
                    132:        // 今はコア側でペンディング処理をしているのでこっち側は起きたことを全部
                    133:        // 通知する。
                    134:        // 割り込みレベルが 0 に下がる時にはこのディレイは不要のはず。
                    135:        if (level != 0) {
                    136:                event.time = intdelay;
                    137:        } else {
                    138:                event.time = 0;
                    139:        }
                    140:        event.code = level;
                    141:        event.Start();
1.1       root      142: }
                    143: 
                    144: // A-Line 命令エミュレーションのコールバックを指定。
                    145: void
                    146: MPU680x0Device::SetALineCallback(bool (*callback)(m68kcpu *, void*), void *arg)
                    147: {
                    148:        cpu->aline_callback = callback;
                    149:        cpu->aline_arg = arg;
                    150: }
                    151: 
                    152: // F-Line 命令エミュレーションのコールバックを指定。
                    153: void
                    154: MPU680x0Device::SetFLineCallback(bool (*callback)(m68kcpu *, void*), void *arg)
                    155: {
                    156:        cpu->fline_callback = callback;
                    157:        cpu->fline_arg = arg;
                    158: }
                    159: 
1.1.1.10  root      160: // MPU ホールト時の MPU からのコールバック関数
                    161: /*static*/ void
                    162: MPU680x0Device::HaltCallback(void *arg)
                    163: {
                    164:        UIMessage::Post(UIMessage::HALT);
                    165: }
                    166: 
                    167: // MPU からのアクセスをエミュレート
                    168: uint64
                    169: MPU680x0Device::Read8(uint32 addr)
                    170: {
                    171:        try {
                    172:                return m68030_read_8(cpu, addr);
                    173:        } catch (...) {
                    174:                return (uint64)-1;
                    175:        }
                    176: }
                    177: 
                    178: uint64
                    179: MPU680x0Device::Read16(uint32 addr)
                    180: {
                    181:        try {
                    182:                return m68030_read_16(cpu, addr);
                    183:        } catch (...) {
                    184:                return (uint64)-1;
                    185:        }
                    186: }
                    187: 
                    188: uint64
                    189: MPU680x0Device::Read32(uint32 addr)
1.1.1.2   root      190: {
1.1.1.10  root      191:        try {
                    192:                return m68030_read_32(cpu, addr);
                    193:        } catch (...) {
                    194:                return (uint64)-1;
                    195:        }
                    196: }
                    197: 
                    198: uint64
                    199: MPU680x0Device::Write8(uint32 addr, uint32 data)
                    200: {
                    201:        try {
                    202:                m68030_write_8(cpu, addr, data);
                    203:                return 0;
                    204:        } catch (...) {
                    205:                return (uint64)-1;
                    206:        }
                    207: }
                    208: 
                    209: uint64
                    210: MPU680x0Device::Write16(uint32 addr, uint32 data)
                    211: {
                    212:        try {
                    213:                m68030_write_16(cpu, addr, data);
                    214:                return 0;
                    215:        } catch (...) {
                    216:                return (uint64)-1;
                    217:        }
                    218: }
                    219: 
                    220: uint64
                    221: MPU680x0Device::Write32(uint32 addr, uint32 data)
                    222: {
                    223:        try {
                    224:                m68030_write_32(cpu, addr, data);
                    225:                return 0;
                    226:        } catch (...) {
                    227:                return (uint64)-1;
                    228:        }
1.1.1.2   root      229: }
                    230: 
1.1       root      231: // モニター更新 (レジスタウィンドウ)
1.1.1.3   root      232: void
1.1.1.9   root      233: MPU680x0Device::MonitorUpdateReg(Monitor *, TextScreen& screen)
1.1       root      234: {
                    235:        m68kreg reg;
                    236:        uint32 ppc;
                    237:        int x;
                    238:        int y;
                    239: 
1.1.1.9   root      240:        screen.Clear();
1.1       root      241: 
                    242:        // ローカルにコピー
                    243:        // ただし PPC だけ reg 構造体ではなく cpu クラス側にある
                    244:        reg = cpu->reg;
                    245:        ppc = cpu->ppc;
                    246: 
                    247:        // データレジスタ、アドレスレジスタ
                    248:        for (int i = 0; i < 4; i++) {
1.1.1.9   root      249:                screen.Print(0, i, "D%d:%08x D%d:%08x  A%d:%08x A%d:%08x",
1.1       root      250:                        i + 0, reg.da[i],
                    251:                        i + 4, reg.da[i + 4],
                    252:                        i + 0, reg.da[i + 8],
                    253:                        i + 4, reg.da[i + 12]);
                    254:        }
                    255: 
                    256:        // 5列目
                    257:        x = 50;
                    258:        // SR
1.1.1.9   root      259:        screen.Print(x, 0, "SR:%04x(%c%c%c%c%c)",
1.1       root      260:                (reg.sr_h() | reg.ccr.Get()),
                    261:                (reg.ccr.IsX()) ? 'X' : '-',
                    262:                (reg.ccr.IsN()) ? 'N' : '-',
                    263:                (reg.ccr.IsZ()) ? 'Z' : '-',
                    264:                (reg.ccr.IsV()) ? 'V' : '-',
                    265:                (reg.ccr.IsC()) ? 'C' : '-');
                    266: 
                    267:        // VBR
1.1.1.9   root      268:        screen.Print(x, 1, "VBR:%08x", reg.vbr);
1.1       root      269: 
                    270:        // *SP
                    271:        uint ms = (reg.s ? 2 : 0) | (reg.m ? 1 : 0); // T1 T0 S M
                    272:        if (ms == 3) {
                    273:                // Supervisor (Master) mode (A7=MSP, USP/ISP)
1.1.1.9   root      274:                screen.Print(x, 2, TA::Disable, "USP:%08x", reg.usp);
                    275:                screen.Print(x, 3, TA::Disable, "ISP:%08x", reg.isp);
1.1       root      276:        } else if (ms == 2) {
                    277:                // Supervisor (Interrupt) mode (A7=ISP, USP/MSP)
1.1.1.9   root      278:                screen.Print(x, 2, TA::Disable, "USP:%08x", reg.usp);
                    279:                screen.Print(x, 3, TA::Disable, "MSP:%08x", reg.msp);
1.1       root      280:        } else {
                    281:                // User mode (A7=USP, ISP/MSP)
1.1.1.9   root      282:                screen.Print(x, 2, TA::Disable, "ISP:%08x", reg.isp);
                    283:                screen.Print(x, 3, TA::Disable, "MSP:%08x", reg.msp);
1.1       root      284:        }
                    285: 
                    286:        // 6列目
                    287:        // PC:  01234567
                    288:        // SFC:1   DFC:1
                    289:        // CACR:01234567
                    290:        // CAAR:01234567
                    291:        x = 66;
1.1.1.9   root      292:        screen.Print(x, 0, "PC:  %08x", ppc);
                    293:        screen.Print(x, 1, "SFC:%d  DFC:%d", reg.sfc, reg.dfc);
                    294:        screen.Print(x, 2, "CACR:%08x", reg.cacr);
                    295:        screen.Print(x, 3, "CAAR:%08x", reg.caar);
1.1       root      296: 
                    297:        // XXX どこに置くのがいいか
                    298:        if (reg.state == 0) {
1.1.1.9   root      299:                screen.Puts(25, 4, "State: Running");
1.1       root      300:        } else if (reg.state == CPU_REQ_STOP) {
1.1.1.9   root      301:                screen.Puts(25, 4, "State: STOP instruction");
1.1       root      302:        } else if (reg.state == CPU_REQ_HALT) {
1.1.1.9   root      303:                screen.Puts(25, 4, TA::On, "State: Double Bus Fault");
1.1       root      304:        }
                    305: 
                    306:        // MMU
                    307:        x = 0;
                    308:        y = 4;
1.1.1.9   root      309:        screen.Puts(x, y++, "<MMU>");
                    310:        screen.Print(x, y,     "SRP:%08x_%08x", reg.srp.h, reg.srp.l);
                    311:        screen.Print(x, y + 1, "CRP:%08x_%08x", reg.crp.h, reg.crp.l);
1.1       root      312:        x += 23;
                    313:        for (int i = 0; i < 2; i++) {
                    314:                uint32 tt = reg.tt[i];
1.1.1.9   root      315:                screen.Print(x, y + i, "TT%d:%08x(%c%c%c)",
1.1       root      316:                        i, tt,
                    317:                        (tt & m68030TT::E)   ? 'E' : '-',
                    318:                        (tt & m68030TT::CI)  ? 'C' : '-',
                    319:                        (tt & m68030TT::RWM) ? '-' : ((tt & m68030TT::RW)  ? 'R' : 'W'));
                    320:        }
                    321:        x += 19;
1.1.1.9   root      322:        screen.Print(x, y, "TC:%08x(%c%c%c)",
1.1       root      323:                reg.tc,
                    324:                (reg.tc & m68030TC::TC_E)   ? 'E' : '-',
                    325:                (reg.tc & m68030TC::TC_SRE) ? 'S' : '-',
                    326:                (reg.tc & m68030TC::TC_FCL) ? 'F' : '-');
1.1.1.9   root      327:        screen.Print(x, y + 1, "MMUSR: %04x(%c%c%c%c%c%c%c N=%d)",
1.1       root      328:                reg.mmusr,
                    329:                (reg.mmusr & m68030MMUSR::B) ? 'B' : '-',
                    330:                (reg.mmusr & m68030MMUSR::L) ? 'L' : '-',
                    331:                (reg.mmusr & m68030MMUSR::S) ? 'S' : '-',
                    332:                (reg.mmusr & m68030MMUSR::W) ? 'W' : '-',
                    333:                (reg.mmusr & m68030MMUSR::I) ? 'I' : '-',
                    334:                (reg.mmusr & m68030MMUSR::M) ? 'M' : '-',
                    335:                (reg.mmusr & m68030MMUSR::T) ? 'T' : '-',
                    336:                (reg.mmusr & m68030MMUSR::N));
                    337: 
                    338:        // FPU
                    339:        x = 0;
                    340:        y = 7;
1.1.1.9   root      341:        screen.Puts(x, y++, "<FPU>");
1.1       root      342:        for (int i = 0; i < 8; i++) {
1.1.1.9   root      343:                screen.Print(x, y + i, "FP%d:%04x_%08x_%08x (%-20s)",
1.1       root      344:                        i,
                    345:                        reg.fpframe.fpf_regs[i * 3 + 0] >> 16,
                    346:                        reg.fpframe.fpf_regs[i * 3 + 1],
                    347:                        reg.fpframe.fpf_regs[i * 3 + 2],
                    348:                        "not yet");
                    349:        }
                    350: 
                    351:        x = 51;
                    352: 
                    353:        // FPCR
                    354:        static const char * const rpstr[] = {
                    355:                ".EXT",
                    356:                ".SGL",
                    357:                ".DBL",
                    358:                ".???",
                    359:        };
                    360:        static const char * const rmstr[] = {
                    361:                "Near",
                    362:                "Zero",
                    363:                "Minus",
                    364:                "Plus",
                    365:        };
                    366:        uint32 fpcr = reg.fpframe.fpf_fpcr;
1.1.1.9   root      367:        screen.Print(x, y++, "FPCR:%04x", fpcr);
1.1.1.11! root      368:        screen.Puts(x +  2, y, TA::OnOff(fpcr & 0x8000), "BS");
        !           369:        screen.Puts(x +  5, y, TA::OnOff(fpcr & 0x4000), "SN");
        !           370:        screen.Puts(x +  8, y, TA::OnOff(fpcr & 0x2000), "OP");
        !           371:        screen.Puts(x + 11, y, TA::OnOff(fpcr & 0x1000), "OV");
        !           372:        screen.Puts(x + 14, y, TA::OnOff(fpcr & 0x0800), "UF");
        !           373:        screen.Puts(x + 17, y, TA::OnOff(fpcr & 0x0400), "DZ");
        !           374:        screen.Puts(x + 20, y, TA::OnOff(fpcr & 0x0200), "I2");
        !           375:        screen.Puts(x + 23, y, TA::OnOff(fpcr & 0x0100), "I1");
        !           376:        y++;
1.1.1.9   root      377:        screen.Print(x + 2, y++, "RP=%s RM=%s",
1.1       root      378:                rpstr[(fpcr >> 6) & 3],
                    379:                rmstr[(fpcr >> 4) & 3]);
                    380: 
                    381:        // FPSR
                    382:        uint32 fpsr = reg.fpframe.fpf_fpsr;
                    383:        uint32 cc = fpsr >> 24;
1.1.1.9   root      384:        screen.Print(x, y++, "FPSR:%08x", fpsr);
1.1.1.11! root      385:        screen.Puts(x +  2, y, TA::OnOff(cc & 0x08), "N");
        !           386:        screen.Puts(x +  4, y, TA::OnOff(cc & 0x04), "Z");
        !           387:        screen.Puts(x +  6, y, TA::OnOff(cc & 0x02), "Inf");
        !           388:        screen.Puts(x + 10, y, TA::OnOff(cc & 0x01), "NAN");
        !           389:        screen.Print(x + 14, y, "Q=$%02x", (fpsr >> 16) & 0xff);
        !           390:        y++;
        !           391:        screen.Puts(x +  2, y, TA::OnOff(fpsr & 0x8000), "BS");
        !           392:        screen.Puts(x +  5, y, TA::OnOff(fpsr & 0x4000), "SN");
        !           393:        screen.Puts(x +  8, y, TA::OnOff(fpsr & 0x2000), "OP");
        !           394:        screen.Puts(x + 11, y, TA::OnOff(fpsr & 0x1000), "OV");
        !           395:        screen.Puts(x + 14, y, TA::OnOff(fpsr & 0x0800), "UF");
        !           396:        screen.Puts(x + 17, y, TA::OnOff(fpsr & 0x0400), "DZ");
        !           397:        screen.Puts(x + 20, y, TA::OnOff(fpsr & 0x0200), "I2");
        !           398:        screen.Puts(x + 23, y, TA::OnOff(fpsr & 0x0100), "I1");
        !           399:        y++;
        !           400:        screen.Puts(x +  2, y, TA::OnOff(fpsr & 0x80), "IOP");
        !           401:        screen.Puts(x +  6, y, TA::OnOff(fpsr & 0x80), "OVFL");
        !           402:        screen.Puts(x + 11, y, TA::OnOff(fpsr & 0x80), "UNFL");
        !           403:        screen.Puts(x + 16, y, TA::OnOff(fpsr & 0x80), "DZ");
        !           404:        screen.Puts(x + 19, y, TA::OnOff(fpsr & 0x80), "INEX");
        !           405:        y++;
1.1       root      406: 
                    407:        // FPIAR
1.1.1.9   root      408:        screen.Print(x, y++, "FPIAR:%08x", reg.fpframe.fpf_fpiar);
1.1       root      409: }
                    410: 
1.1.1.9   root      411: // モニター更新 (ATC)
1.1.1.3   root      412: void
1.1.1.9   root      413: MPU680x0Device::MonitorUpdateATC(Monitor *, TextScreen& screen)
1.1       root      414: {
                    415:        m68030ATCTable *table;
                    416: #if !defined(ATC_SINGLE)
                    417:        struct {
                    418:                int fc;
                    419:                const char *name;
                    420:        } fclist[] = {
                    421:                { 1,    "User/Data" },
                    422:                { 2,    "User/Program" },
                    423:                { 5,    "Super/Data" },
                    424:                { 6,    "Super/Program" },
                    425:        };
                    426: 
1.1.1.9   root      427:        screen.Clear();
1.1       root      428: 
                    429:        // 行数は左端にだけ
                    430:        for (int i = 0; i < m68030ATCTable::LINES; i++) {
1.1.1.9   root      431:                screen.Print(0, i + 2, "%02d:", i);
1.1       root      432:        }
                    433: 
                    434:        for (int t = 0; t < countof(fclist); t++) {
                    435:                int x = t * 32 + 4;
                    436:                int fc = fclist[t].fc;
                    437:                const char *name = fclist[t].name;
                    438:                double r;
                    439:                int i;
                    440: 
                    441:                table = &cpu->atc.tables[fc];
1.1.1.9   root      442:                screen.Print(x, 0, "FC=%d %s", fc, name);
                    443:                screen.Puts(x, 1, "LAddr    PAddr   Flag Hit%  Age");
1.1       root      444:                // 先に統計用の母数を計算
                    445:                uint64 total = 0;
                    446:                for (i = 0; i < countof(table->hit); i++) {
                    447:                        total += table->hit[i];
                    448:                }
                    449:                total += table->hit_head;
                    450: 
                    451:                // エントリ表示
                    452:                for (i = 0; i < countof(table->line); i++) {
                    453:                        m68030ATCLine& a = table->line[i];
1.1.1.2   root      454:                        TA attr;
1.1       root      455:                        if (a.IsInvalid()) {
                    456:                                attr = TA::Disable;
                    457:                        } else if (table->head == &a) {
                    458:                                attr = TA::Em;
                    459:                        } else {
                    460:                                attr = TA::Normal;
                    461:                        }
                    462: 
1.1.1.9   root      463:                        screen.Print(x, i + 2, attr, "%08x %08x %c%c%c",
1.1       root      464:                                a.GetLAddr(),
                    465:                                a.GetPAddr(),
                    466:                                a.IsBusError() ? 'B' : '-',
                    467:                                a.IsWProtect() ? 'P' : '-',
                    468:                                a.IsModified() ? 'M' : '-');
                    469:                }
                    470:                // ヘッドのヒット率
1.1.1.9   root      471:                screen.Puts(x + 0, i + 2, "head");
1.1       root      472:                r = (double)table->hit_head * 100 / total;
                    473:                if (!isnan(r)) {
1.1.1.9   root      474:                        screen.Print(x + 5, i + 2, "%4.1f%%", r);
1.1       root      475:                }
                    476:                // 配列のヒット率とミス率
1.1.1.9   root      477:                screen.Puts(x + 17, i + 2, "miss");
1.1       root      478:                for (i = 0; i < countof(table->hit); i++) {
                    479:                        r = (double)(table->hit[i] * 100) / total;
                    480:                        if (!isnan(r)) {
1.1.1.9   root      481:                                screen.Print(x + 22, i + 2, "%4.1f%%", r);
1.1       root      482:                        }
                    483:                }
                    484:                // カウンタ
                    485:                // 分かりやすさのため最大値からの差(距離)を表示
                    486:                for (i = 0; i < countof(table->line); i++) {
                    487:                        m68030ATCLine& a = table->line[i];
                    488:                        if (!a.IsInvalid()) {
1.1.1.9   root      489:                                screen.Print(x + 27, i + 2, "%4d", table->head->age - a.age);
1.1       root      490:                        }
                    491:                }
                    492:        }
                    493: #else
                    494:        m68030ATCLine *a;
                    495:        int i;
                    496: 
                    497:        table = &cpu->atc.tables[0];
1.1.1.9   root      498:        screen.Clear();
1.1       root      499: 
1.1.1.9   root      500:        screen.Puts(0, 0, "No. FC    LAddr    PAddr   Flag");
1.1       root      501:        for (a = table->head, i = 0; a; a = a->next, i++) {
1.1.1.9   root      502:                screen.Print(0, i + 1, "%02d:", i);
1.1       root      503:                if (!a->IsInvalid()) {
                    504:                        char dp;
                    505:                        switch (a->fc & 3) {
                    506:                         case 1:        dp = 'D';       break;
                    507:                         case 2:        dp = 'P';       break;
                    508:                         default:       dp = '?';       break;
                    509:                        }
1.1.1.9   root      510:                        screen.Print(4, i + 1, "%d(%c%c):%08x %08x %c%c%c",
1.1       root      511:                                a->fc,
                    512:                                (a->fc & 4) ? 'S' : 'U',
                    513:                                dp,
                    514:                                a->GetLAddr(), a->GetPAddr(),
                    515:                                a->IsBusError() ? 'B' : '-',
                    516:                                a->IsWProtect() ? 'W' : '-',
                    517:                                a->IsModified() ? 'M' : '-');
                    518:                }
                    519:        }
                    520: #endif
                    521: }
1.1.1.9   root      522: 
                    523: // CPU 側からのコールバック。RESET 命令ハンドラ
                    524: void
                    525: m68030_reset_inst(m68kcpu *cpu)
                    526: {
                    527:        gVM->ResetByMPU();
                    528: }

unix.superglobalmegacorp.com

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