--- nono/vm/mpu88xx0.cpp 2026/04/29 17:05:18 1.1.1.13 +++ nono/vm/mpu88xx0.cpp 2026/04/29 17:05:38 1.1.1.17 @@ -37,10 +37,25 @@ MPU88xx0Device::MPU88xx0Device() cmmu[0].reset(new m88200(this, 7)); cmmu[1].reset(new m88200(this, 6)); + // 設定の初期値。 + + // MPU のデフォルトは xxx.usr バグ修正済みのバージョンに設定する。 + // 所有している実機にあわせ 0xb。OpenBSD の + // sys/arch/m88k/m88k/m88100_machdep.c::m88100_apply_patches() 参照。 + gConfig->SetDefault("m88100-version", 0xb); + + // CMMU のデフォルトは xmem の writeback バグが修正されているバージョンに + // 設定する。所有している実機にあわせ 0x9。 + // OpenBSD の sys/arch/m88k/m88k/m8820x_machdep.c::m8820x_apr_cmode() 参照。 + gConfig->SetDefault("m88200-version", 0x9); + + // 例外カウンタ + excep_counter.resize(512); + // レジスタモニター - monitor.func = ToMonitorCallback(&MPU88xx0Device::MonitorUpdate); - monitor.SetSize(79, 28); - monitor.Regist(ID_MONITOR_MPUREG); + monitor = gMonitorManager->Regist(ID_MONITOR_MPUREG, this); + monitor->func = ToMonitorCallback(&MPU88xx0Device::MonitorUpdate); + monitor->SetSize(79, 25); } // デストラクタ @@ -64,6 +79,17 @@ MPU88xx0Device::Init() const ConfigItem& item_altname = gConfig->Find(".m88k-altname"); m88100disasm::use_altname = item_altname.AsInt(); + // MPU のバージョン。 + const ConfigItem& item_88100ver = gConfig->Find("m88100-version"); + uint ver88100 = item_88100ver.AsInt(); + reg.pid = (ver88100 << 1) | M88100::PID_MASTER; + + // CMMU のバージョン。 + const ConfigItem& item_88200ver = gConfig->Find("m88200-version"); + uint ver88200 = item_88200ver.AsInt(); + cmmu[0]->SetVersion(ver88200); + cmmu[1]->SetVersion(ver88200); + return true; } @@ -111,7 +137,10 @@ MPU88xx0Device::ResetHard(bool poweron) // なるので、これだけここでも初期化しておく。 reg.xip = 0; } + + // intr_pending は m88100core.cpp の ExecNormal() 中のコメント参照。 resetting = true; + intr_pending = 1; // リセット例外を 8+256 クロック後に起こす。 // 8+256 は、電源オン時に最低これだけアサートしなければならないという値 @@ -222,10 +251,10 @@ void MPU88xx0Device::ChangeState(uint32 new_state) { // new_state (CPU_STATE_*) と - // RequestCPUMode() の引数 Syncer::SCHED_CPU_* は + // RequestCPUMode() の引数 Syncer::SYNCMODE_CPU_* は // 実は同じ値なのでそのまま渡してよいことにする。 - static_assert(CPU_STATE_NORMAL == Syncer::SCHED_CPU_NORMAL, ""); - static_assert(CPU_STATE_STOP == Syncer::SCHED_CPU_STOP, ""); + static_assert(CPU_STATE_NORMAL == Syncer::SYNCMODE_CPU_NORMAL, ""); + static_assert(CPU_STATE_STOP == Syncer::SYNCMODE_CPU_STOP, ""); if (cpu_state != new_state) { cpu_state = new_state; @@ -274,113 +303,6 @@ MPU88xx0Device::SetFLineCallback(bool (* fline_arg = arg; } -// MPU からのアクセスをエミュレート -uint64 -MPU88xx0Device::Read8(uint32 addr) -{ - return cmmu[1]->load_8(addr); -} - -uint64 -MPU88xx0Device::Read16(uint32 addr) -{ - if ((addr & 1) == 0) { - return cmmu[1]->load_16(addr); - } else { - uint64 h, l; - h = Read8(addr); - if ((int64)h < 0) { - return h; - } - l = Read8(addr + 1); - if ((int64)l < 0) { - return l; - } - return (h << 8) | l; - } -} - -uint64 -MPU88xx0Device::Read32(uint32 addr) -{ - if ((addr & 3) == 0) { - return cmmu[1]->load_32(addr); - } else if ((addr & 1) == 0) { - uint64 h, l; - h = Read16(addr); - if ((int64)h < 0) { - return h; - } - l = Read16(addr + 2); - if ((int64)l < 0) { - return l; - } - return (h << 16) | l; - } else { - uint64 h, m, l; - h = Read8(addr); - if ((int64)h < 0) { - return h; - } - m = Read16(addr + 1); - if ((int64)m < 0) { - return m; - } - l = Read8(addr + 3); - if ((int64)l < 0) { - return l; - } - return (h << 24) | (m << 8) | l; - } -} - -uint64 -MPU88xx0Device::Write8(uint32 addr, uint32 data) -{ - return cmmu[1]->store_8(addr, data & 0xff); -} - -uint64 -MPU88xx0Device::Write16(uint32 addr, uint32 data) -{ - if ((addr & 1) == 0) { - return cmmu[1]->store_16(addr, data & 0xffff); - } else { - uint64 r; - r = Write8(addr, data >> 8); - if ((int64)r < 0) { - return r; - } - return Write8(addr + 1, data); - } -} - -uint64 -MPU88xx0Device::Write32(uint32 addr, uint32 data) -{ - if ((addr & 3) == 0) { - return cmmu[1]->store_32(addr, data); - } else if ((addr & 1) == 0) { - uint64 r; - r = Write16(addr, data >> 16); - if ((int64)r < 0) { - return r; - } - return Write16(addr + 2, data); - } else { - uint64 r; - r = Write8(addr, data >> 24); - if ((int64)r < 0) { - return r; - } - r = Write16(addr + 1, data >> 8); - if ((int64)r < 0) { - return r; - } - return Write8(addr + 3, data); - } -} - #define FA(val, bit) TA::OnOff((val) & M88100::bit) // モニター更新 @@ -396,82 +318,77 @@ MPU88xx0Device::MonitorUpdate(Monitor *, // ローカルにコピー tmp = reg; - // - for (int i = 0; i < countof(reg.r); i++) { - screen.Print((i / 8) * 14, i % 8, "r%-2d:%08x", i, tmp.r[i]); + // 汎用レジスタ + for (uint i = 0; i < countof(reg.r); i++) { + screen.Print((i / 8) * 14, i % 8, "r%-2u:%08x", i, tmp.r[i]); + } + + // 制御レジスタ (上段右) + x = 57; + y = 0; + for (int i = 0; i < 4; i++) { + int rn = 17 + i; + screen.Print(x, y++, "sr%u(cr%u):%08x", i, rn, tmp.cr[rn]); } + screen.Print(x, y++, "ssbr(cr3):%08x", tmp.ssbr); + for (int i = 0; i < 3; i++) { + screen.Print(x, y++, "%s(cr%u):%08x:%c%c", + m88100reg::sipname[i], 4 + i, + (tmp.cr[4 + i] & M88100::SIP_MASK), + (tmp.cr[4 + i] & M88100::SIP_V) ? 'V' : '-', + (tmp.cr[4 + i] & M88100::SIP_E) ? 'E' : '-'); + } + screen.Print(x, y++, "vbr (cr7):%08x", tmp.vbr); - // 制御レジスタ + // 制御レジスタ(中段上; *IP) x = 0; y = 9; - screen.Print(x, y++, "pid (cr0):%08x(Arch=$%02x Ver=$%02x MC=%s)", + screen.Print(x, y++, "xip:%08x (op:%08x:%c)", + tmp.xip, (uint32)tmp.opX, OpIsBusErr(tmp.opX) ? 'B' : '-'); + screen.Print(x, y++, "nip:%08x (op:%08x:%c)", + tmp.nip, (uint32)tmp.opF, OpIsBusErr(tmp.opF) ? 'B' : '-'); + screen.Print(x, y++, "fip:%08x", tmp.fip); + + // 制御レジスタ 中段上; pid,*psr) + x = 30; + y = 9; + screen.Print(x, y++, "pid(cr0):%08x(Arch=$%02x Ver=$%02x MC=%s)", tmp.pid, (tmp.pid >> 8) & 0xff, (tmp.pid >> 1) & 0x7f, (tmp.pid & 1) ? "Master" : "Checker"); - screen.Print(x, y, "psr (cr1):%08x(", tmp.psr); + screen.Print(x, y, "psr(cr1):%08x(", tmp.psr); + x--; screen.Puts(x + 19, y, FA(tmp.psr, PSR_SUPER), "S"); - screen.Puts(x + 21, y, - ((tmp.psr & M88100::PSR_BO_LE) ? "BO=LE" : "BO=BE")); - screen.Puts(x + 27, y, FA(tmp.psr, PSR_SER), "SER"); - screen.Puts(x + 31, y, FA(tmp.psr, PSR_C), "Cy"); - screen.Puts(x + 34, y, FA(tmp.psr, PSR_SFD1), "SFD1"); - screen.Puts(x + 39, y, FA(tmp.psr, PSR_MXM), "MXM"); - screen.Puts(x + 43, y, FA(tmp.psr, PSR_IND), "IND"); - screen.Puts(x + 47, y, FA(tmp.psr, PSR_SFRZ), "SFRZ"); - screen.Puts(x + 51, y, ")"); + screen.Puts(x + 21, y, ((tmp.psr & M88100::PSR_BO_LE) ? "LE" : "BE")); + screen.Puts(x + 24, y, FA(tmp.psr, PSR_SER), "SER"); + screen.Puts(x + 28, y, FA(tmp.psr, PSR_C), "Cy"); + screen.Puts(x + 31, y, FA(tmp.psr, PSR_SFD1), "SFD1"); + screen.Puts(x + 36, y, FA(tmp.psr, PSR_MXM), "MXM"); + screen.Puts(x + 40, y, FA(tmp.psr, PSR_IND), "IND"); + screen.Puts(x + 44, y, FA(tmp.psr, PSR_SFRZ), "SFRZ"); + screen.Puts(x + 48, y, ")"); y++; screen.Print(x, y, "epsr(cr2):%08x(", tmp.epsr); screen.Puts(x + 19, y, FA(tmp.epsr, PSR_SUPER), "S"); - screen.Puts(x + 21, y, - ((tmp.epsr& M88100::PSR_BO_LE) ? "BO=LE" : "BO=BE")); - screen.Puts(x + 27, y, FA(tmp.epsr, PSR_SER), "SER"); - screen.Puts(x + 31, y, FA(tmp.epsr, PSR_C), "Cy"); - screen.Puts(x + 34, y, FA(tmp.epsr, PSR_SFD1), "SFD1"); - screen.Puts(x + 39, y, FA(tmp.epsr, PSR_MXM), "MXM"); - screen.Puts(x + 43, y, FA(tmp.epsr, PSR_IND), "IND"); - screen.Puts(x + 47, y, FA(tmp.epsr, PSR_SFRZ), "SFRZ"); - screen.Puts(x + 51, y, ")"); + screen.Puts(x + 21, y, ((tmp.epsr& M88100::PSR_BO_LE) ? "LE" : "BE")); + screen.Puts(x + 24, y, FA(tmp.epsr, PSR_SER), "SER"); + screen.Puts(x + 28, y, FA(tmp.epsr, PSR_C), "Cy"); + screen.Puts(x + 31, y, FA(tmp.epsr, PSR_SFD1), "SFD1"); + screen.Puts(x + 36, y, FA(tmp.epsr, PSR_MXM), "MXM"); + screen.Puts(x + 40, y, FA(tmp.epsr, PSR_IND), "IND"); + screen.Puts(x + 44, y, FA(tmp.epsr, PSR_SFRZ), "SFRZ"); + screen.Puts(x + 48, y, ")"); - // 制御レジスタ(左中; *IP) - x = 0; + // MMU レジスタ(中段下) y = 12; - screen.Print(x, y + 0, "xip:%08x opX:%08x(%c)", - tmp.xip, (uint32)tmp.opX, - OpIsBusErr(tmp.opX) ? 'B' : '-'); - screen.Print(x, y + 1, "nip:%08x opF:%08x(%c)", - tmp.nip, (uint32)tmp.opF, - OpIsBusErr(tmp.opF) ? 'B' : '-'); - screen.Print(x, y + 2, "fip:%08x", tmp.fip); - - // 制御レジスタ (S*IP) - x = 32; - for (int i = 0; i < 3; i++) { - screen.Print(x, y + i, "%s(cr%d):%08x:%c%c", - m88100reg::sipname[i], 4 + i, - (tmp.cr[4 + i] & M88100::SIP_MASK), - (tmp.cr[4 + i] & M88100::SIP_V) ? 'V' : '-', - (tmp.cr[4 + i] & M88100::SIP_E) ? 'E' : '-'); - } - - // 制御レジスタ(右中) - x = 55; - y = 9; - for (int i = 0; i < 4; i++) { - int rn = 17 + i; - screen.Print(x, y++, "sr%d(cr%d):%08x", i, rn, tmp.cr[rn]); - } - screen.Print(x, y++, "ssbr(cr3):%08x", tmp.ssbr); - screen.Print(x, y++, "vbr (cr7):%08x", tmp.vbr); - - // MMU レジスタ(次段) - y = 15; - for (int i = 0; i <= 2; i++) { - int dt = 8 + i * 3; - int dd = 9 + i * 3; - int da = 10 + i * 3; + for (uint i = 0; i <= 2; i++) { + uint dt = 8 + i * 3; + uint dd = 9 + i * 3; + uint da = 10 + i * 3; - screen.Print(0, y, "dmt%d(cr%-2d):%04x", + // DMT は "cr8 " があるので左揃え + screen.Print(0, y, "dmt%u(cr%-2u):%04x", i, dt, (tmp.cr[dt] & 0xffff)); screen.Puts(15, y, "(b,s,d,l,rx, s,en ,w,v)"); screen.Puts(16, y, (tmp.cr[dt] & M88100::DM_BO) ? "B" : "-"); @@ -479,7 +396,7 @@ MPU88xx0Device::MonitorUpdate(Monitor *, screen.Puts(20, y, (tmp.cr[dt] & M88100::DM_DOUB1) ? "D" : "-"); screen.Puts(22, y, (tmp.cr[dt] & M88100::DM_LOCK) ? "L" : "-"); // カンマが自然に見えるようにここだけカンマも含めて前詰めで出力 - screen.Print(25, y, "%d,", + screen.Print(25, y, "%u,", (tmp.cr[dt] & M88100::DM_DREG_MASK) >> 7); screen.Puts(28, y, (tmp.cr[dt] & M88100::DM_SIGNED) ? "S" : "-"); uint32 en = (tmp.cr[dt] & M88100::DM_EN_MASK) >> 2; @@ -487,8 +404,9 @@ MPU88xx0Device::MonitorUpdate(Monitor *, screen.Puts(35, y, (tmp.cr[dt] & M88100::DM_WRITE) ? "W" : "-"); screen.Puts(37, y, (tmp.cr[dt] & M88100::DM_VALID) ? "V" : "-"); - screen.Print(40, y, "dmd%d(cr%-2d):%08x", i, dd, tmp.cr[dd]); - screen.Print(60, y, "dma%d(cr%2d):%08x", i, da, tmp.cr[da]); + // DMD は "cr9 " があるので左揃え + screen.Print(40, y, "dmd%u(cr%-2u):%08x", i, dd, tmp.cr[dd]); + screen.Print(60, y, "dma%u(cr%2u):%08x", i, da, tmp.cr[da]); y++; } y++; @@ -508,7 +426,7 @@ MPU88xx0Device::MonitorUpdate(Monitor *, y++; screen.Print(0, y++, - "fppt(fcr5): %08x(OpCode=%%%c%c%c%c%c T1=%d T2=%d TD=%d Dest=r%d)", + "fppt(fcr5): %08x(OpCode=%%%c%c%c%c%c T1=%u T2=%u TD=%u Dest=r%u)", tmp.fppt, ((tmp.fppt >> 15) & 1) + '0', ((tmp.fppt >> 14) & 1) + '0', @@ -533,7 +451,7 @@ MPU88xx0Device::MonitorUpdate(Monitor *, y++; x = 21; - screen.Print(0, y, "fpit(fcr8): %08x(OpCode=%%%c%c%c%c%c TD=%d", + screen.Print(0, y, "fpit(fcr8): %08x(OpCode=%%%c%c%c%c%c TD=%u", tmp.fpit, ((tmp.fpit >> 15) & 1) + '0', ((tmp.fpit >> 14) & 1) + '0', @@ -546,7 +464,7 @@ MPU88xx0Device::MonitorUpdate(Monitor *, screen.Puts(x + 29, y, FA(tmp.fpit, FPIT_EFUNF), "EUNF"); screen.Puts(x + 34, y, FA(tmp.fpit, FPIT_EFOVF), "EOVF"); screen.Puts(x + 39, y, FA(tmp.fpit, FPIT_EFINX), "EINX"); - screen.Print(x + 44, y, "Dest=r%d)", tmp.fpit & M88100::FPIT_DEST); + screen.Print(x + 44, y, "Dest=r%u)", tmp.fpit & M88100::FPIT_DEST); y++; uint32 sign = (tmp.fprh & M88100::FPRH_SIGN);