--- nono/vm/mainbus_x68k.cpp 2026/04/29 17:05:24 1.1 +++ nono/vm/mainbus_x68k.cpp 2026/04/29 17:05:32 1.1.1.3 @@ -31,6 +31,7 @@ #include "extram.h" #include "interrupt.h" #include "mainapp.h" +#include "monitor.h" #include "x68kio.h" // コンストラクタ @@ -44,15 +45,13 @@ X68kMainbus::X68kMainbus() // デバイスの割り当ては Init() で行っている。 - // モニタの表示外観は Mainbus24 と同じ。 - monitor.func = ToMonitorCallback(&X68kMainbus::MonitorUpdate); - monitor.SetSize(75, 33); - monitor.Regist(ID_MONITOR_MAINBUS); + monitor = gMonitorManager->Regist(ID_MONITOR_MAINBUS, this); + monitor->func = ToMonitorCallback(&X68kMainbus::MonitorUpdate); + monitor->SetSize(75, 33); - monitor_accstat.func = + accstat_monitor->func = ToMonitorCallback(&X68kMainbus::MonitorUpdateAccStat); - monitor_accstat.SetSize(80, 2 + 16 + 3); - monitor_accstat.Regist(ID_MONITOR_ACCSTAT); + accstat_monitor->SetSize(80, 2 + 32 + 3); } // デストラクタ @@ -79,6 +78,9 @@ X68kMainbus::Init() bool X68kMainbus::InitMainbus() { + int extstart; + int extsize; + // 拡張メモリはサイズが確定した後のここで配置。 extsize = pExtRAM->GetSizeMB(); @@ -102,6 +104,12 @@ X68kMainbus::InitMainbus() return false; } + // アクセス統計のデバイスがある領域。 + accstat_avail[0] = 0x80; + for (int i = extstart / 16; i < (extstart + extsize) / 16; i++) { + accstat_avail[i / 8] |= 0x80U >> (i % 8); + } + return true; } @@ -193,85 +201,57 @@ X68kMainbus::IsIntio(uint32 addr) const return is_intio[(addr >> 24) & 0xff]; } -#define READ(NN) do { \ - uint32 pa = addr.Addr(); \ - if (IsIntio(pa)) { \ - /* 内蔵 16MB を 1MB 単位で */ \ - accstat_read[(pa >> 20) & 0x0f] = ACC_READ; \ - return pX68kIO->__CONCAT(Read,NN)(addr); \ - } else { \ - /* 拡張メモリのアドレスは折り返しは起きない */ \ - accstat_read[pa >> 20] = ACC_READ; \ - return pExtRAM->__CONCAT(Read,NN)(pa); \ - } \ -} while (0) - -#define WRITE(NN) do { \ - uint32 pa = addr.Addr(); \ - if (IsIntio(pa)) { \ - /* 内蔵 16MB を 1MB 単位で */ \ - accstat_write[(pa >> 20) & 0x0f] = ACC_WRITE; \ - return pX68kIO->__CONCAT(Write,NN)(addr, data); \ - } else { \ - /* 拡張メモリのアドレスは折り返しは起きない */ \ - accstat_write[pa >> 20] = ACC_WRITE; \ - return pExtRAM->__CONCAT(Write,NN)(pa, data); \ - } \ -} while (0) - -busdata -X68kMainbus::Read8(busaddr addr) -{ - READ(8); -} - -busdata -X68kMainbus::Read16(busaddr addr) -{ - READ(16); -} +// 内蔵 16MB 分で折り返す +#define ACCSTAT_INTIO(pa) \ + (((pa) >> AccStat::SHIFT) & ((1U << (24 - AccStat::SHIFT)) - 1)) busdata -X68kMainbus::Read32(busaddr addr) +X68kMainbus::Read(busaddr addr) { - READ(32); -} - -busdata -X68kMainbus::Write8(busaddr addr, uint32 data) -{ - WRITE(8); -} - -busdata -X68kMainbus::Write16(busaddr addr, uint32 data) -{ - WRITE(16); + uint32 pa = addr.Addr(); + if (IsIntio(pa)) { + // 内蔵 16MB を 2MB 単位で + accstat_read[ACCSTAT_INTIO(pa)] = AccStat::READ; + return pX68kIO->Read(addr); + } else { + // 拡張メモリのアドレスは折り返しは起きない + accstat_read[pa >> AccStat::SHIFT] = AccStat::READ; + return pExtRAM->Read(addr); + } } busdata -X68kMainbus::Write32(busaddr addr, uint32 data) +X68kMainbus::Write(busaddr addr, uint32 data) { - WRITE(32); + uint32 pa = addr.Addr(); + if (IsIntio(pa)) { + // 内蔵 16MB を 2MB 単位で + accstat_write[ACCSTAT_INTIO(pa)] = AccStat::WRITE; + return pX68kIO->Write(addr, data); + } else { \ + // 拡張メモリのアドレスは折り返しは起きない + accstat_write[pa >> AccStat::SHIFT] = AccStat::WRITE; + return pExtRAM->Write(addr, data); + } } busdata -X68kMainbus::Peek8(uint32 addr) +X68kMainbus::Peek1(uint32 addr) { if (IsIntio(addr)) { - return pX68kIO->Peek8(addr); + return pX68kIO->Peek1(addr); } else { - return pExtRAM->Peek8(addr); + return pExtRAM->Peek1(addr); } } bool -X68kMainbus::Poke8(uint32 addr, uint32 data) +X68kMainbus::Poke1(uint32 addr, uint32 data) { if (IsIntio(addr)) { - return pX68kIO->Poke8(addr, data); + return pX68kIO->Poke1(addr, data); } else { - return pExtRAM->Poke8(addr, data); + return pExtRAM->Poke1(addr, data); } } @@ -302,71 +282,27 @@ X68kMainbus::MonitorUpdate(Monitor *, Te } void -X68kMainbus::MonitorUpdateAccStat(Monitor *, TextScreen& screen) +X68kMainbus::MonitorUpdateAccStat(Monitor *monitor_, TextScreen& screen) { - std::array acc; - std::array accbank; - - // R|W をマージしながらコピー。 - for (int i = 0, iend = acc.size(); i < iend; i += 4) { - uint32 tmp = 0; - tmp |= *(uint32 *)&accstat_read[i]; - tmp |= *(uint32 *)&accstat_write[i]; - *(uint32 *)&acc[i] = tmp; - } + // メインバス空間は親クラス側の処理そのまま。 + inherited::MonitorUpdateAccStat(monitor_, screen); - // 読んだのでリセット。 - std::fill(accstat_read.begin(), accstat_read.end(), 0); - std::fill(accstat_write.begin(), accstat_write.end(), 0); - - // バンクメモリ。 + // バンクメモリ側の情報取得。 for (int n = 0; n < bankram.size(); n++) { if (bankram[n]) { - bankram[n]->FetchAccStat(&accbank[n * 16]); - } - } - - screen.Clear(); - screen.Print(0, 0, - "Shows only the first 1GB. 1MB/char. " - "'R':Read, 'W':Write, 'A':Read+Write"); - screen.Print(12, 1, "0123456789ABCDEF"); - for (int i = 1; i < 4; i++) { - screen.Print(12 + 17 * i, 1, "+$0%x", i); - } - for (int y = 0; y < acc.size() / 64; y++) { - screen.Print(0, y + 2, "$%02x00'0000:", y * 0x04); - } - - // 拡張メモリ部分。 - for (int i = extstart, end = extstart + extsize; i < end; i++) { - uint op = acc[i] & 3; - uint8 ch = ".RWA"[op]; - int y = 2 + i / 64; - int x = 12 + (i % 64) + ((i % 64) / 16)/*区切りの空白分*/; - screen.Putc(x, y, ch); - } - - // 内蔵I/O 部分。 - { - std::array buf; - char *d = &buf[0]; - for (int i = 0; i < 16; i++) { - uint op = acc[i] & 3; - *d++ = ".RWA"[op]; + bankram[n]->FetchAccStat(&accbank[n * AccStat::BANKLEN]); } - *d = '\0'; - screen.Puts(12, 2, &buf[0]); } - // バンクメモリ。 - for (int n = 0; n < 2; n++) { - screen.Print(0, 19 + n, "BankMem #%d:", n); + // バンクメモリ側の描画。 + for (int n = 0; n < bankram.size(); n++) { + int y = 35 + n; + screen.Print(0, y, "BankMem #%u:", n); if (bankram[n]) { - for (int i = 0; i < 16; i++) { - uint op = accbank[n * 16 + i] & 3; + for (int i = 0; i < AccStat::BANKLEN; i++) { + uint op = accbank[n * AccStat::BANKLEN + i] & 3; uint8 ch = ".RWA"[op]; - screen.Putc(12 + i, 19 + n, ch); + screen.Putc(12 + i, y, ch); } } }